home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / edit / thesrc20.zip / commutil.c < prev    next >
C/C++ Source or Header  |  1995-01-26  |  93KB  |  2,803 lines

  1. /***********************************************************************/
  2. /* COMMUTIL.C -                                                        */
  3. /* This file contains all utility functions used when processing       */
  4. /* commands.                                                           */
  5. /***********************************************************************/
  6. /*
  7.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  8.  * Copyright (C) 1991-1995 Mark Hessling
  9.  *
  10.  * This program is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU General Public License as
  12.  * published by the Free Software Foundation; either version 2 of
  13.  * the License, or any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to:
  22.  *
  23.  *    The Free Software Foundation, Inc.
  24.  *    675 Mass Ave,
  25.  *    Cambridge, MA 02139 USA.
  26.  *
  27.  *
  28.  * If you make modifications to this software that you feel increases
  29.  * it usefulness for the rest of the community, please email the
  30.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  31.  * This software is going to be maintained and enhanced as deemed
  32.  * necessary by the community.
  33.  *
  34.  * Mark Hessling                     email: M.Hessling@gu.edu.au
  35.  * 36 David Road                     Phone: +61 7 849 7731
  36.  * Holland Park                      Fax:   +61 7 875 5314
  37.  * QLD 4121
  38.  * Australia
  39.  */
  40.  
  41. /*
  42. $Id: commutil.c 2.0 1995/01/26 16:30:23 MH Release MH $
  43. */
  44.  
  45. #include <stdio.h>
  46.  
  47. #include "the.h"
  48. #include "key.h"
  49. #include "command.h"
  50. #include "proto.h"
  51.  
  52.  static CHARTYPE cmd[MAX_SAVED_COMMANDS][MAX_COMMAND_LENGTH];
  53.  static short last_cmd=(-1),current_cmd=0,number_cmds=0,offset_cmd=0;
  54.  
  55. /*---------------------------------------------------------------------*/
  56. /* The following two static variables are for reserving space for the  */
  57. /* parameters of a command. Space for temp_params is allocated and     */
  58. /* freed in the.c. If the size of the string to be placed into         */
  59. /* temp_params is > length_temp_params, reallocate a larger area and   */
  60. /* set the value of length_temp_params to reflect the new size.        */
  61. /*---------------------------------------------------------------------*/
  62.  static CHARTYPE *temp_params=NULL;
  63.  static unsigned short length_temp_params=0;
  64. /*---------------------------------------------------------------------*/
  65. /* The following two static variables are for reserving space for the  */
  66. /* directories in a macro path. Space for temp_macros is allocated and */
  67. /* freed in the.c. If the size of the string to be placed into         */
  68. /* temp_macros is > length_temp_macros  reallocate a larger area and   */
  69. /* set the value of length_temp_macros to reflect the new size.        */
  70. /*---------------------------------------------------------------------*/
  71.  static CHARTYPE *temp_macros=NULL;
  72.  static unsigned short length_temp_macros=0;
  73. /*---------------------------------------------------------------------*/
  74. /* The following two static variables are for reserving space for the  */
  75. /* contents of   a command. Space for tmp_cmd     is allocated and     */
  76. /* freed in the.c. If the size of the string to be placed into         */
  77. /* tmp_cmd     is > length_tmp_cmd    , reallocate a larger area and   */
  78. /* set the value of length_tmp_cmd     to reflect the new size.        */
  79. /*---------------------------------------------------------------------*/
  80.  static CHARTYPE *tmp_cmd=NULL;
  81.  static unsigned short length_tmp_cmd=0;
  82. /*---------------------------------------------------------------------*/
  83. /* The following two        variables are for reserving space for the  */
  84. /* contents of   a command. Space for temp_cmd    is allocated and     */
  85. /* freed in the.c. If the size of the string to be placed into         */
  86. /* temp_cmd    is > length_temp_cmd   , reallocate a larger area and   */
  87. /* set the value of length_temp_cmd    to reflect the new size.        */
  88. /*---------------------------------------------------------------------*/
  89.  CHARTYPE *temp_cmd=NULL;
  90.  static unsigned short length_temp_cmd=0;
  91. /*---------------------------------------------------------------------*/
  92. /* The following two are to specify the first and last items in the    */
  93. /* linked list for key definitions.                                    */
  94. /*---------------------------------------------------------------------*/
  95. DEFINE *first_define=NULL;
  96. DEFINE *last_define=NULL;
  97.  
  98. bool clear_command=TRUE;
  99.  
  100. /***********************************************************************/
  101. #ifdef PROTO
  102. CHARTYPE *get_key_name(int key)
  103. #else
  104. CHARTYPE *get_key_name(key)
  105. int key;
  106. #endif
  107. /***********************************************************************/
  108. {
  109. /*--------------------------- local data ------------------------------*/
  110.  register short i=0;
  111.  CHARTYPE *keyname=NULL;
  112. /*--------------------------- processing ------------------------------*/
  113. #ifdef TRACE
  114.  trace_function("commutil.c:get_key_name");
  115. #endif
  116. /*---------------------------------------------------------------------*/
  117. /* Get name of key...                                                  */
  118. /*---------------------------------------------------------------------*/
  119.  for (i=0;key_table[i].mnemonic!=NULL;i++)
  120.     {
  121.      if (key == key_table[i].key_value)
  122.        {
  123.         keyname = key_table[i].mnemonic;
  124.         break;
  125.        }
  126.     }
  127. #ifdef TRACE
  128.  trace_return();
  129. #endif
  130.  return(keyname);
  131. }
  132. /***********************************************************************/
  133. #ifdef PROTO
  134. CHARTYPE *get_key_definition(int key)
  135. #else
  136. CHARTYPE *get_key_definition(key)
  137. int key;
  138. #endif
  139. /***********************************************************************/
  140. {
  141. /*--------------------------- local data ------------------------------*/
  142.  register short i=0;
  143.  DEFINE *curr=NULL;
  144.  CHARTYPE delim[2];
  145.  bool key_defined=FALSE;
  146.  bool valid_key=FALSE;
  147.  bool first_time=TRUE;
  148.  bool locate_command=FALSE;
  149.  CHARTYPE *keyname=NULL;
  150. /*--------------------------- processing ------------------------------*/
  151. #ifdef TRACE
  152.  trace_function("commutil.c:get_key_definition");
  153. #endif
  154. /*---------------------------------------------------------------------*/
  155. /* First determine if the key is a named key.                          */
  156. /*---------------------------------------------------------------------*/
  157.  keyname = get_key_name(key);
  158.  if (keyname != NULL)
  159.    {
  160.     strcpy(temp_cmd,"Key: ");
  161.     valid_key = TRUE;
  162.     strcat(temp_cmd,keyname);
  163.    }
  164. /*---------------------------------------------------------------------*/
  165. /* If key is invalid,  show it as a character and decimal; provided it */
  166. /* is an ASCII or extended character.                                  */
  167. /*---------------------------------------------------------------------*/
  168.  if (!valid_key && key < 256)
  169.     sprintf(temp_cmd,"Key: %c \\%d",(CHARTYPE)key,key);
  170. /*---------------------------------------------------------------------*/
  171. /* Next check to see if the key has been "defined".                    */
  172. /*---------------------------------------------------------------------*/
  173.  delim[1] = '\0';
  174.  delim[0] = CURRENT_VIEW->linend_value;
  175.  curr = first_define;
  176.  while(curr != NULL)
  177.   {
  178.    if (key == curr->def_funkey)
  179.      {
  180.       key_defined = TRUE;
  181.       if (first_time)
  182.          strcat(temp_cmd," - assigned to '");
  183.       else
  184.         {
  185.          strcat(temp_cmd,delim);
  186.         }
  187. /*---------------------------------------------------------------------*/
  188. /* Append the command to the string.                                   */
  189. /*---------------------------------------------------------------------*/
  190.       strcat(temp_cmd,command[curr->def_command].text);
  191. /*---------------------------------------------------------------------*/
  192. /* Append any parameters.                                              */
  193. /*---------------------------------------------------------------------*/
  194.       if (strcmp(curr->def_params,"") != 0)
  195.         {
  196.          strcat(temp_cmd," ");
  197.          strcat(temp_cmd,curr->def_params);
  198.         }
  199.       first_time = FALSE;
  200.      }
  201.    curr = curr->next;
  202.   }
  203.  if (key_defined)
  204.    {
  205.     strcat(temp_cmd,"'");
  206. #ifdef TRACE
  207.     trace_return();
  208. #endif
  209.     return(temp_cmd);
  210.    }
  211. /*---------------------------------------------------------------------*/
  212. /* If not, check for the default function key values.                  */
  213. /*---------------------------------------------------------------------*/
  214.  for (i=0;command[i].text != NULL;i++)
  215.     {
  216.       if (key == command[i].funkey)
  217.         {
  218.          strcat(temp_cmd," - assigned to '");
  219. /*---------------------------------------------------------------------*/
  220. /* If a SET command, prefix with 'set'                                 */
  221. /*---------------------------------------------------------------------*/
  222.          if (command[i].set_command)
  223.             strcat(temp_cmd,"set ");
  224. /*---------------------------------------------------------------------*/
  225. /* If a SOS command, prefix with 'sos'                                 */
  226. /*---------------------------------------------------------------------*/
  227.          if (command[i].sos_command)
  228.             strcat(temp_cmd,"sos ");
  229. /*---------------------------------------------------------------------*/
  230. /* Append the command name.                                            */
  231. /*---------------------------------------------------------------------*/
  232.          strcat(temp_cmd,command[i].text);
  233. /*---------------------------------------------------------------------*/
  234. /* Append any parameters.                                              */
  235. /*---------------------------------------------------------------------*/
  236.          if (strcmp(command[i].params,"") != 0)
  237.            {
  238.             strcat(temp_cmd," ");
  239.             strcat(temp_cmd,command[i].params);
  240.            }
  241.          strcat(temp_cmd,"'");
  242. #ifdef TRACE
  243.          trace_return();
  244. #endif
  245.          return(temp_cmd);
  246.         }
  247.     }
  248. /*---------------------------------------------------------------------*/
  249. /* If none of the above, it is unassigned                              */
  250. /*---------------------------------------------------------------------*/
  251.  strcat(temp_cmd," - unassigned");
  252. #ifdef TRACE
  253.  trace_return();
  254. #endif
  255.  return(temp_cmd);
  256. }
  257. /***********************************************************************/
  258. #ifdef PROTO
  259. short function_key(int key)
  260. #else
  261. short function_key(key)
  262. int key;
  263. #endif
  264. /***********************************************************************/
  265. {
  266. /*------------------------- external data -----------------------------*/
  267.  extern CHARTYPE number_of_files;
  268.  extern bool readonly;
  269. /*--------------------------- local data ------------------------------*/
  270.  register short i=0;
  271.  DEFINE *curr=NULL;
  272.  bool key_defined=FALSE;
  273.  short rc=RC_OK;
  274.  CHARTYPE *cmd=NULL;
  275. /*--------------------------- processing ------------------------------*/
  276. #ifdef TRACE
  277.  trace_function("commutil.c:function_key");
  278. #endif
  279. /*---------------------------------------------------------------------*/
  280. /* First check to see if the function key has been redefined.          */
  281. /*---------------------------------------------------------------------*/
  282.  curr = first_define;
  283.  while(curr != NULL)
  284.   {
  285.    if (key == curr->def_funkey)
  286.      {
  287.       key_defined = TRUE;
  288. /*---------------------------------------------------------------------*/
  289. /* If running in read-only mode and the function selected is not valid */
  290. /* display an error.                                                   */
  291. /*---------------------------------------------------------------------*/
  292.       if (readonly && !command[curr->def_command].valid_in_readonly)
  293.         {
  294.          display_error(56,"",FALSE);
  295.          rc = RC_INVALID_ENVIRON;
  296.          break;
  297.         }
  298. /*---------------------------------------------------------------------*/
  299. /* If there are no more files in the ring, and the command is not a    */
  300. /* command to edit a new file, then ignore the command.                */
  301. /*---------------------------------------------------------------------*/
  302.       if (number_of_files == 0
  303.       &&  !command[curr->def_command].edit_command)
  304.         {
  305.          rc = RC_OK;
  306.          break;
  307.         }
  308.       if ((cmd = (CHARTYPE *)my_strdup(curr->def_params)) == NULL)
  309.         {
  310.          display_error(30,(CHARTYPE *)"",FALSE);
  311. #ifdef TRACE
  312.          trace_return();
  313. #endif
  314.          return(RC_OUT_OF_MEMORY);
  315.         }
  316.       rc = (*command[curr->def_command].function)((CHARTYPE *)cmd);
  317.       (*the_free)(cmd);
  318.       if (rc != RC_OK
  319.       &&  rc != RC_TOF_EOF_REACHED
  320.       &&  rc != RC_NO_LINES_CHANGED
  321.       &&  rc != RC_TARGET_NOT_FOUND)
  322.          break;
  323.      }
  324.    curr = curr->next;
  325.   }
  326.  if (key_defined)
  327.    {
  328. #ifdef TRACE
  329.     trace_return();
  330. #endif
  331.     return(rc);
  332.    }
  333. /*---------------------------------------------------------------------*/
  334. /* If not, check for the default function key values.                  */
  335. /*---------------------------------------------------------------------*/
  336.  for (i=0;command[i].text != NULL;i++)
  337.       if (key == command[i].funkey)
  338.         {
  339. /*---------------------------------------------------------------------*/
  340. /* If running in read-only mode and the function selected is not valid */
  341. /* display an error.                                                   */
  342. /*---------------------------------------------------------------------*/
  343.          if (readonly && !command[i].valid_in_readonly)
  344.            {
  345.             display_error(56,"",FALSE);
  346.             rc = RC_INVALID_ENVIRON;
  347.            }
  348.          else
  349.            {
  350.             if ((cmd = (CHARTYPE *)my_strdup(command[i].params)) == NULL)
  351.               {
  352.                display_error(30,(CHARTYPE *)"",FALSE);
  353. #ifdef TRACE
  354.                trace_return();
  355. #endif
  356.                return(RC_OUT_OF_MEMORY);
  357.               }
  358.             rc = (*command[i].function)((CHARTYPE *)cmd);
  359.             (*the_free)(cmd);
  360.            }
  361. #ifdef TRACE
  362.          trace_return();
  363. #endif
  364.          return(rc);
  365.         }
  366. #ifdef TRACE
  367.  trace_return();
  368. #endif
  369.  return(RAW_KEY);
  370. }
  371. /***********************************************************************/
  372. #ifdef PROTO
  373. short command_line(CHARTYPE *cmd_line,bool command_only)
  374. #else
  375. short command_line(cmd_line,command_only)
  376. CHARTYPE *cmd_line;
  377. bool command_only;
  378. #endif
  379. /***********************************************************************/
  380. {
  381. /*------------------------- external data -----------------------------*/
  382.  extern bool error_on_screen;
  383.  extern CHARTYPE *last_target;
  384.  extern bool LINEND_STATUSx;
  385.  extern CHARTYPE LINEND_VALUEx;
  386.  extern bool in_macro;
  387.  extern CHARTYPE number_of_files;
  388.  extern short lastrc;
  389.  extern bool readonly;
  390.  extern bool in_profile;
  391. /*--------------------------- local data ------------------------------*/
  392.  bool valid_command=FALSE;
  393.  bool linend_status=(number_of_files) ? CURRENT_VIEW->linend_status : LINEND_STATUSx;
  394.  CHARTYPE linend_value=0;
  395.  register short i=0,j=0;
  396.  short rc=RC_OK,pos=0;
  397.  LINETYPE num_lines=0L;
  398.  CHARTYPE *cmd[MAX_COMMANDS+1];
  399.  unsigned short num_commands=0;
  400.  CHARTYPE command_delim[2];
  401.  CHARTYPE *command_entered=NULL;
  402.  CHARTYPE *cl_cmd=NULL;
  403.  CHARTYPE *cl_param=NULL;
  404.  TARGET target;
  405.  short target_type=TARGET_NORMAL|TARGET_SPARE;
  406.  bool display_parse_error=FALSE;
  407. /*--------------------------- processing ------------------------------*/
  408. #ifdef TRACE
  409.  trace_function("commutil.c:command_line");
  410. #endif
  411. /*---------------------------------------------------------------------*/
  412. /* If the command line is blank, just return.                          */
  413. /*---------------------------------------------------------------------*/
  414.  if (strlen(cmd_line) == 0)
  415.    {
  416.     if (!in_profile)
  417.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  418. #ifdef TRACE
  419.     trace_return();
  420. #endif
  421.     return(RC_OK);
  422.    }
  423. /*---------------------------------------------------------------------*/
  424. /* Set up values for LINEND for later processing...                    */
  425. /*---------------------------------------------------------------------*/
  426.  if (number_of_files == 0)
  427.    {
  428.     linend_status = LINEND_STATUSx;
  429.     linend_value = LINEND_VALUEx;
  430.    }
  431.  else
  432.    {
  433.     linend_status = CURRENT_VIEW->linend_status;
  434.     linend_value = CURRENT_VIEW->linend_value;
  435.    }
  436. /*---------------------------------------------------------------------*/
  437. /* If the command is to be kept displayed on the command line...       */
  438. /*---------------------------------------------------------------------*/
  439.  if (*(cmd_line) == '&')
  440.    {
  441.     cmd_line++;
  442.     clear_command = FALSE;
  443.    }
  444.  else
  445.     if (!(in_macro && !clear_command))
  446.        clear_command = TRUE;
  447. /*---------------------------------------------------------------------*/
  448. /* Copy the incoming cmd_line, so we can play with it.                 */
  449. /*---------------------------------------------------------------------*/
  450.  if ((command_entered = (CHARTYPE *)my_strdup(cmd_line)) == NULL)
  451.    {
  452.     display_error(30,(CHARTYPE *)"",FALSE);
  453. #ifdef TRACE
  454.     trace_return();
  455. #endif
  456.     return(RC_OUT_OF_MEMORY);
  457.    }
  458. /*---------------------------------------------------------------------*/
  459. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  460. /* it is split into a command and its parameters.                      */
  461. /*---------------------------------------------------------------------*/
  462.  if ((cl_cmd = (CHARTYPE *)(*the_malloc)((strlen(cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
  463.    {
  464.     display_error(30,(CHARTYPE *)"",FALSE);
  465. #ifdef TRACE
  466.     trace_return();
  467. #endif
  468.     return(RC_OUT_OF_MEMORY);
  469.    }
  470.  if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen(cmd_line)+1)*sizeof(CHARTYPE))) == NULL)
  471.    {
  472.     display_error(30,(CHARTYPE *)"",FALSE);
  473. #ifdef TRACE
  474.     trace_return();
  475. #endif
  476.     return(RC_OUT_OF_MEMORY);
  477.    }
  478. /*---------------------------------------------------------------------*/
  479. /* If [SET] LINENd is set to ON, split the line up into a number of    */
  480. /* individual commands.                                                */
  481. /*---------------------------------------------------------------------*/
  482.  if (linend_status
  483.  && !define_command(cmd_line))
  484.    {
  485.     command_delim[0] = linend_value;
  486.     command_delim[1] = '\0';
  487.     num_commands = command_split(cmd_line,cmd,MAX_COMMANDS,command_delim,command_entered);
  488.    }
  489.  else
  490.    {
  491.     cmd[0] = command_entered;
  492.     num_commands = 1;
  493.    }
  494. /*---------------------------------------------------------------------*/
  495. /* For each command entered, split it up into command and params, and  */
  496. /* process it...                                                       */
  497. /*---------------------------------------------------------------------*/
  498.  for (j=0;j<num_commands;j++)
  499.    {
  500.     valid_command = FALSE;
  501.     split_command(cmd[j],cl_cmd,cl_param);
  502. /*---------------------------------------------------------------------*/
  503. /* Here is where we could check for synonyms first.                    */
  504. /*---------------------------------------------------------------------*/
  505.     if (!command_only)
  506.        ;       /* get synonym for entered command */
  507. /*---------------------------------------------------------------------*/
  508. /* Look up the command in the command array in command.h               */
  509. /*---------------------------------------------------------------------*/
  510.     for (i=0;command[i].text != NULL;i++)
  511.       {
  512. /*---------------------------------------------------------------------*/
  513. /* If no command text, continue.                                       */
  514. /*---------------------------------------------------------------------*/
  515.        if (strcmp(command[i].text,"") == 0)
  516.          continue;
  517.        rc = RC_OK;
  518. /*---------------------------------------------------------------------*/
  519. /* Check that the supplied command matches the command for the length  */
  520. /* of the command and that the length is at least as long as the       */
  521. /* necessary significance.                                             */
  522. /*---------------------------------------------------------------------*/
  523.        if (equal(command[i].text,cl_cmd,command[i].min_len)
  524.        && command[i].min_len != 0
  525.        && !command[i].sos_command)
  526.          {
  527.           if (in_profile
  528.           && !command[i].valid_profile_command)
  529.             {
  530.              display_error(24,command[i].text,FALSE);
  531.              lastrc = rc = RC_INVALID_ENVIRON;
  532.              break;
  533.             }
  534.           valid_command = TRUE;
  535. /*---------------------------------------------------------------------*/
  536. /* Here is a big kludge. Because only a few commands need leading      */
  537. /* spaces to be present in temp_params and all other commands barf at  */
  538. /* leading spaces, we need to left truncate temp_params for most       */
  539. /* commands.                                                           */
  540. /*---------------------------------------------------------------------*/
  541.           if (command[i].strip_param)
  542.             {
  543.              pos = strzne(cl_param,' ');
  544.              if (pos == (-1))
  545.                 pos = 0;
  546.             }
  547.           else
  548.              pos = 0;
  549. /*---------------------------------------------------------------------*/
  550. /* If running in read-only mode and the function selected is not valid */
  551. /* display an error.                                                   */
  552. /*---------------------------------------------------------------------*/
  553.          if (readonly && !command[i].valid_in_readonly)
  554.            {
  555.             display_error(56,"",FALSE);
  556.             rc = RC_INVALID_ENVIRON;
  557.             break;
  558.            }
  559. /*---------------------------------------------------------------------*/
  560. /* If there are no more files in the ring, and the command is not a    */
  561. /* command to edit a new file, then ignore the command.                */
  562. /*---------------------------------------------------------------------*/
  563.          if (number_of_files == 0
  564.          &&  !command[i].edit_command)
  565.            {
  566.             rc = RC_OK;
  567.             break;
  568.            }
  569. /*---------------------------------------------------------------------*/
  570. /* Now call the function associated with the supplied command string   */
  571. /* and the possibly stripped parameters.                               */
  572. /*---------------------------------------------------------------------*/
  573.           lastrc = rc = (*command[i].function)(cl_param+pos);
  574.           break;
  575.          }
  576.       }
  577. /*---------------------------------------------------------------------*/
  578. /* If an error occurred while executing a command above, break.        */
  579. /*---------------------------------------------------------------------*/
  580.     if (rc != RC_OK
  581.     &&  rc != RC_TOF_EOF_REACHED)
  582.        break;
  583. /*---------------------------------------------------------------------*/
  584. /* If we found and successfully executed a command above, process the  */
  585. /* next command.                                                       */
  586. /*---------------------------------------------------------------------*/
  587.     if (valid_command)
  588.        continue;
  589. /*---------------------------------------------------------------------*/
  590. /* To get here the command was not a 'command'; check if a valid target*/
  591. /*---------------------------------------------------------------------*/
  592.     initialise_target(&target);
  593.     if (!CURRENT_VIEW->imp_macro
  594.     &&  !CURRENT_VIEW->imp_os)
  595.        display_parse_error = TRUE;
  596.     else
  597.        display_parse_error = FALSE;
  598.     rc = validate_target(cmd[j],&target,target_type,get_true_line(),display_parse_error,TRUE);
  599. /*---------------------------------------------------------------------*/
  600. /* If a valid target, but target not found, continue...                */
  601. /*---------------------------------------------------------------------*/
  602.     if (rc == RC_TARGET_NOT_FOUND)
  603.       {
  604.        strcpy(last_target,target.string);
  605.        free_target(&target);
  606.        lastrc = rc = RC_TARGET_NOT_FOUND;
  607.        continue;
  608.       }
  609. /*---------------------------------------------------------------------*/
  610. /* If a valid target and found, go there and execute any following     */
  611. /* command.                                                            */
  612. /*---------------------------------------------------------------------*/
  613.     if (rc == RC_OK)
  614.       {
  615.        strcpy(last_target,target.string);
  616.        if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  617.           lastrc = rc = advance_current_line(target.num_lines);
  618.        else
  619.           lastrc = rc = advance_focus_line(target.num_lines);
  620.        if ((rc == RC_OK
  621.            || rc == RC_TOF_EOF_REACHED)
  622.        &&  target.spare != (-1))
  623.           rc = lastrc = command_line(strtrunc(target.rt[target.spare].string),FALSE);
  624.        free_target(&target);
  625.        continue;
  626.       }
  627.     free_target(&target);
  628. /*---------------------------------------------------------------------*/
  629. /* If return is RC_INVALID_OPERAND, check if command is OS command...  */
  630. /*---------------------------------------------------------------------*/
  631.     if (cmd[j][0] == '!')
  632.       {
  633.        strcpy(command_entered,cmd[j]);
  634.        lastrc = rc = Os(command_entered+1);
  635.        continue;
  636.       }
  637. /*---------------------------------------------------------------------*/
  638. /* ...or if command is a macro command (as long as IMPMACRO is ON) and */
  639. /* command_only is FALSE...                                            */
  640. /*---------------------------------------------------------------------*/
  641.     if (CURRENT_VIEW->imp_macro
  642.     && !command_only)
  643.       {
  644.        strcpy(command_entered,cmd[j]);
  645.        if (CURRENT_VIEW->imp_os)
  646.          {
  647.           rc = execute_macro(command_entered,FALSE);
  648.           if (rc != RC_FILE_NOT_FOUND)
  649.             {
  650.              lastrc = rc;
  651.              continue;
  652.             }
  653.          }
  654.        else
  655.          {
  656.           rc = execute_macro(command_entered,TRUE);
  657.           if (rc == RC_FILE_NOT_FOUND)
  658.             {
  659.              lastrc = rc = RC_NOT_COMMAND;
  660.              break;
  661.             }
  662.           else
  663.             {
  664.              lastrc = rc;
  665.              continue;
  666.             }
  667.          }
  668.       }
  669. /*---------------------------------------------------------------------*/
  670. /* ...or if command is an OS command (as long as IMPOS is ON).         */
  671. /*---------------------------------------------------------------------*/
  672.     if (CURRENT_VIEW->imp_os)
  673.       {
  674.        error_on_screen = FALSE;
  675.        strcpy(command_entered,cmd[j]);
  676.        rc = Os(command_entered);
  677.       }
  678.     else
  679.       {
  680.        display_error(21,cmd[j],FALSE);
  681.        rc = RC_NOT_COMMAND;
  682.       }
  683. /*---------------------------------------------------------------------*/
  684. /* If the 'command' is not a command then do not process any more.     */
  685. /*---------------------------------------------------------------------*/
  686.     lastrc = rc;
  687.     if (rc == RC_NOT_COMMAND)
  688.        break;
  689.    }
  690.  cleanup_command_line();
  691.  (*the_free)(command_entered);
  692.  (*the_free)(cl_cmd);
  693.  (*the_free)(cl_param);
  694.  
  695. #ifdef TRACE
  696.  trace_return();
  697. #endif
  698.  return(rc);
  699. }
  700. /***********************************************************************/
  701. #ifdef PROTO
  702. void cleanup_command_line(void)
  703. #else
  704. void cleanup_command_line()
  705. #endif
  706. /***********************************************************************/
  707. {
  708. /*-------------------------- external data ----------------------------*/
  709.  extern CHARTYPE *cmd_rec;
  710.  extern unsigned short cmd_rec_len;
  711.  extern bool in_macro;
  712.  extern CHARTYPE number_of_views;
  713.  extern bool in_profile;
  714. /*--------------------------- local data ------------------------------*/
  715. /*--------------------------- processing ------------------------------*/
  716. #ifdef TRACE
  717.  trace_function("commutil.c:cleanup_command_line");
  718. #endif
  719.  if (in_profile || in_macro || number_of_views == 0)
  720.    {
  721. #ifdef TRACE
  722.     trace_return();
  723. #endif
  724.     return;
  725.    }
  726.  if (clear_command)
  727.    {
  728.     if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  729.       {
  730.        wmove(CURRENT_WINDOW_COMMAND,0,0);
  731.        my_wclrtoeol(CURRENT_WINDOW_COMMAND);
  732.       }
  733.     memset(cmd_rec,' ',COLS);
  734.     cmd_rec_len = 0;
  735.    }
  736.  if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  737.     wmove(CURRENT_WINDOW_COMMAND,0,0);
  738. #ifdef TRACE
  739.  trace_return();
  740. #endif
  741.  return;
  742. }
  743. /***********************************************************************/
  744. #ifdef PROTO
  745. void split_command(CHARTYPE *cmd_line,CHARTYPE *cmd,CHARTYPE *param)
  746. #else
  747. void split_command(cmd_line,cmd,param)
  748. CHARTYPE *cmd_line,*cmd,*param;
  749. #endif
  750. /***********************************************************************/
  751. /*---------------------------------------------------------------------*/
  752. {
  753. /*--------------------------- local data ------------------------------*/
  754.  short pos=0;
  755.  CHARTYPE *param_ptr=NULL;
  756. /*--------------------------- processing ------------------------------*/
  757. #ifdef TRACE
  758.  trace_function("commutil.c:split_command");
  759. #endif
  760.  strcpy(cmd,cmd_line);
  761.  strtrunc(cmd);
  762.  if ((param_ptr = (CHARTYPE *)strpbrk(cmd," \\/-+@")) == NULL)
  763.     {
  764.      strcpy(param,"");
  765. #ifdef TRACE
  766.      trace_return();
  767. #endif
  768.      return;
  769.     }
  770.  pos = strzne(param_ptr,' ');
  771.  if (param_ptr == cmd
  772.  || pos == (-1))
  773.     {
  774.      strcpy(param,"");
  775. #ifdef TRACE
  776.      trace_return();
  777. #endif
  778.      return;
  779.     }
  780.  strcpy(param,param_ptr+(*(param_ptr) == ' ' ? 1 : 0));
  781.  *(param_ptr) = '\0';
  782. #ifdef TRACE
  783.  trace_return();
  784. #endif
  785.  return;
  786. }
  787. /***********************************************************************/
  788. #ifdef PROTO
  789. short param_split(CHARTYPE *params,CHARTYPE *word[],short words,
  790.                 CHARTYPE *delims,CHARTYPE param_type)
  791. #else
  792. short param_split(params,word,words,delims,param_type)
  793. CHARTYPE *params;
  794. CHARTYPE *word[];
  795. short words;
  796. CHARTYPE *delims;
  797. CHARTYPE param_type;
  798. #endif
  799. /***********************************************************************/
  800. {
  801. /*--------------------------- local data ------------------------------*/
  802.  register short i=0,k=0;
  803.  unsigned short len=0;
  804.  CHARTYPE j=0;
  805.  bool end_of_string=FALSE,end_of_word=FALSE;
  806.  CHARTYPE *param_ptr=NULL;
  807. /*--------------------------- processing ------------------------------*/
  808. #ifdef TRACE
  809.  trace_function("commutil.c:param_split");
  810. #endif
  811. /*---------------------------------------------------------------------*/
  812. /* Allocate some memory to the temporary area.                         */
  813. /*---------------------------------------------------------------------*/
  814.  if (params != NULL)
  815.    {
  816.     if (allocate_temp_space(strlen(params),param_type) != RC_OK)
  817.       {
  818. #ifdef TRACE
  819.       trace_return();
  820. #endif
  821.       return(-1);
  822.       }
  823.    }
  824. /*---------------------------------------------------------------------*/
  825. /* Based on param_type, point param_ptr to appropriate buffer.         */
  826. /*---------------------------------------------------------------------*/
  827.  switch(param_type)
  828.    {
  829.     case TEMP_PARAM:
  830.          param_ptr = temp_params;
  831.          break;
  832.     case TEMP_MACRO:
  833.          param_ptr = temp_macros;
  834.          break;
  835.     case TEMP_TEMP_CMD:
  836.          param_ptr = temp_cmd;
  837.          break;
  838.     default:
  839.          return(-1);
  840.          break;
  841.    }
  842. /*---------------------------------------------------------------------*/
  843. /* In case params is NULL, copy an empty string into param_ptr...      */
  844. /*---------------------------------------------------------------------*/
  845.  if (params == NULL)
  846.     strcpy(param_ptr,"");
  847.  else
  848.     strcpy(param_ptr,params);
  849.  
  850.  for (i=0;i<words;i++)
  851.      word[i] = (CHARTYPE *)"";
  852.  j = 0;
  853.  end_of_string = TRUE;
  854.  len = strlen(param_ptr);
  855.  for (i=0;i<len && j<words;i++)
  856.    {
  857.     end_of_word = FALSE;
  858.     for (k=0;k<strlen(delims);k++)
  859.       {
  860.        if (*(param_ptr+i) == *(delims+k))
  861.           end_of_word = TRUE;
  862.       }
  863.     if (end_of_word)
  864.       {
  865.        *(param_ptr+i) = '\0';
  866.        end_of_string = TRUE;
  867.       }
  868.     else
  869.        if (end_of_string)
  870.          {
  871.           word[j++] = param_ptr+i;
  872.           end_of_string = FALSE;
  873.          }
  874.    }
  875. #ifdef TRACE
  876.  trace_return();
  877. #endif
  878.  return(j);
  879. }
  880. /***********************************************************************/
  881. #ifdef PROTO
  882. short command_split(CHARTYPE *params,CHARTYPE *word[],short words,
  883.                 CHARTYPE *delims,CHARTYPE *buffer)
  884. #else
  885. short command_split(params,word,words,delims,buffer)
  886. CHARTYPE *params;
  887. CHARTYPE *word[];
  888. short words;
  889. CHARTYPE *delims;
  890. CHARTYPE *buffer;
  891. #endif
  892. /***********************************************************************/
  893. {
  894. /*--------------------------- local data ------------------------------*/
  895.  register short i=0,k=0;
  896.  unsigned short len=0;
  897.  CHARTYPE j=0;
  898.  bool end_of_string=FALSE,end_of_word=FALSE;
  899. /*--------------------------- processing ------------------------------*/
  900. #ifdef TRACE
  901.  trace_function("commutil.c:command_split");
  902. #endif
  903. /*---------------------------------------------------------------------*/
  904. /* In case params is NULL, copy an empty string into buffer...         */
  905. /*---------------------------------------------------------------------*/
  906.  if (params == NULL)
  907.     strcpy(buffer,"");
  908.  else
  909.     strcpy(buffer,params);
  910.  
  911.  for (i=0;i<words;i++)
  912.      word[i] = (CHARTYPE *)"";
  913.  j = 0;
  914.  end_of_string = TRUE;
  915.  len = strlen(buffer);
  916.  for (i=0;i<len && j<words;i++)
  917.    {
  918.     end_of_word = FALSE;
  919.     for (k=0;k<strlen(delims);k++)
  920.       {
  921.        if (*(buffer+i) == *(delims+k))
  922.           end_of_word = TRUE;
  923.       }
  924.     if (end_of_word)
  925.       {
  926.        *(buffer+i) = '\0';
  927.        end_of_string = TRUE;
  928.       }
  929.     else
  930.        if (end_of_string)
  931.          {
  932.           word[j++] = buffer+i;
  933.           end_of_string = FALSE;
  934.          }
  935.    }
  936. #ifdef TRACE
  937.  trace_return();
  938. #endif
  939.  return(j);
  940. }
  941. /***********************************************************************/
  942. #ifdef PROTO
  943. LINETYPE get_true_line(void)
  944. #else
  945. LINETYPE get_true_line()
  946. #endif
  947. /***********************************************************************/
  948. {
  949. /*-------------------------- external data ----------------------------*/
  950.  extern bool in_profile;
  951. /*--------------------------- local data ------------------------------*/
  952.  LINETYPE true_line=0L;
  953. /*--------------------------- processing ------------------------------*/
  954. #ifdef TRACE
  955.  trace_function("commutil.c:get_true_line");
  956. #endif
  957. /*---------------------------------------------------------------------*/
  958. /* Determine 'true_line'.                                              */
  959. /*---------------------------------------------------------------------*/
  960.  if (in_profile)
  961.     true_line = CURRENT_VIEW->current_line;
  962.  else
  963.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  964.        true_line = CURRENT_VIEW->current_line;
  965.     else
  966.        true_line = CURRENT_VIEW->focus_line;
  967. #ifdef TRACE
  968.  trace_return();
  969. #endif
  970.  return(true_line);
  971. }
  972. #ifndef MSWIN
  973. /***********************************************************************/
  974. #ifdef PROTO
  975. void print_line(bool close_spooler,LINETYPE true_line,LINETYPE num_lines,
  976.                 short pagesize,CHARTYPE *text,CHARTYPE *line_term)
  977. #else
  978. void print_line(close_spooler,true_line,num_lines,pagesize,text,line_term)
  979. bool close_spooler;
  980. LINETYPE true_line,num_lines;
  981. short pagesize;
  982. CHARTYPE *text;
  983. CHARTYPE *line_term;
  984. #endif
  985. /***********************************************************************/
  986. {
  987. /*------------------------- external data -----------------------------*/
  988. #if defined(UNIX) || defined(OS2)
  989.  extern CHARTYPE *spooler_name;
  990. #endif
  991.  extern bool curses_started;
  992. /*--------------------------- local data ------------------------------*/
  993. #if defined(UNIX) || defined(OS2)
  994.  static bool spooler_open=FALSE;
  995. #  if defined(OS2)
  996.  HFILE Lpt;
  997. #    if defined(__32BIT__)
  998.  ULONG Action=0L;
  999.  ULONG NoWritten=0L;
  1000. #    else
  1001.  USHORT Action=0;
  1002.  USHORT NoWritten=0;
  1003. #    endif
  1004. #  endif
  1005. #endif
  1006.  static FILE *pp;
  1007.  register short i=0;
  1008.  LINETYPE j=0L;
  1009.  LINE *curr=NULL;
  1010.  short line_number=0;
  1011.  LINETYPE num_excluded=0L;
  1012.  LINETYPE abs_num_lines=(num_lines < 0L ? -num_lines : num_lines);
  1013.  short direction=(num_lines < 0L ? DIRECTION_BACKWARD : DIRECTION_FORWARD);
  1014.  unsigned short y=0,x=0;
  1015. /*--------------------------- processing ------------------------------*/
  1016. #ifdef TRACE
  1017.  trace_function("commutil.c:print_line");
  1018. #endif
  1019. #if defined(DOS)
  1020.  pp = stdprn;
  1021. #endif
  1022. #if defined(UNIX) || defined(OS2)
  1023.  if (close_spooler)
  1024.    {
  1025.     if (spooler_open)
  1026.       {
  1027.        spooler_open = FALSE;
  1028. #if defined(OS2)
  1029.        DosClose(Lpt);
  1030. #else
  1031.        pclose(pp);
  1032. #endif
  1033.       }
  1034. #ifdef TRACE
  1035.     trace_return();
  1036. #endif
  1037.     return;
  1038.    }
  1039. #endif
  1040. #if defined(UNIX)
  1041.  if (!spooler_open)
  1042.    {
  1043.     pp = popen(spooler_name,"w");
  1044.     spooler_open = TRUE;
  1045.    }
  1046. #endif
  1047. #if defined(OS2)
  1048.  if (!spooler_open)
  1049.    {
  1050. #ifdef __32BIT__
  1051.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1052.                OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE,(PEAOP2)NULL) != 0)
  1053. #else
  1054.    if (DosOpen(spooler_name, &Lpt, &Action, 0,FILE_NORMAL,FILE_OPEN,
  1055.                OPEN_ACCESS_WRITEONLY|OPEN_SHARE_DENYWRITE,NULL) != 0)
  1056. #endif
  1057.      {
  1058. #ifdef TRACE
  1059.       trace_return();
  1060. #endif
  1061.       return;
  1062.      }
  1063.     spooler_open = TRUE;
  1064.    }
  1065. #endif
  1066.  
  1067.  if (num_lines == 0L)
  1068.    {
  1069. #if defined(OS2)
  1070.     DosWrite(Lpt,text,strlen(text),&NoWritten);
  1071. #else
  1072.     fprintf(pp,"%s%s",text,line_term);
  1073. #endif
  1074. #ifdef TRACE
  1075.     trace_return();
  1076. #endif
  1077.     return;
  1078.    }
  1079. /*---------------------------------------------------------------------*/
  1080. /* Once we get here, we are to print lines from the file.              */
  1081. /*---------------------------------------------------------------------*/
  1082.  post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1083.  if (curses_started)
  1084.    {
  1085.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1086.        getyx(CURRENT_WINDOW_MAIN,y,x);
  1087.     else
  1088.        getyx(CURRENT_WINDOW,y,x);
  1089.    }
  1090.  curr = lll_find(CURRENT_FILE->first_line,true_line);
  1091.  for (j=0L;j<abs_num_lines;j++)
  1092.    {
  1093.     if (in_scope(curr)
  1094.     || CURRENT_VIEW->scope_all)
  1095.       {
  1096.        if (TOF(true_line)
  1097.        ||  BOF(true_line))
  1098.           ;
  1099.        else
  1100.          {
  1101.           if (num_excluded != 0)
  1102.             {
  1103. #if defined(OS2)
  1104.              print_shadow_line(Lpt,line_term,num_excluded);
  1105. #else
  1106.              print_shadow_line(pp,line_term,num_excluded);
  1107. #endif
  1108.              num_excluded = 0L;
  1109.             }
  1110. #if defined(OS2)
  1111.           DosWrite(Lpt,curr->line,curr->length,&NoWritten);
  1112.           DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
  1113. #else
  1114.           for (i=0;i<curr->length;i++)
  1115.               fputc(*(curr->line+i) & A_CHARTEXT,pp);
  1116.           fprintf(pp,"%s",line_term);
  1117. #endif
  1118.           line_number++;
  1119.           if (line_number == pagesize
  1120.           && pagesize != 0)
  1121.             {
  1122. #if defined(OS2)
  1123.              DosWrite(Lpt,"\f",1,&NoWritten);
  1124. #else
  1125.              fputc('\f',pp);
  1126. #endif
  1127.              line_number = 0;
  1128.             }
  1129.          }
  1130.       }
  1131.     else
  1132.        num_excluded++;
  1133. /*---------------------------------------------------------------------*/
  1134. /* Proceed to the next record, even if the current record not in scope.*/
  1135. /*---------------------------------------------------------------------*/
  1136.     true_line += (LINETYPE)direction;
  1137.     if (num_lines < 0L)
  1138.        curr = curr->prev;
  1139.     else
  1140.        curr = curr->next;
  1141.     if (curr == NULL)
  1142.        break;
  1143.    }
  1144. /*---------------------------------------------------------------------*/
  1145. /* If we have a shadow line remaining, print it...                     */
  1146. /*---------------------------------------------------------------------*/
  1147.  if (num_excluded != 0)
  1148.    {
  1149. #if defined(OS2)
  1150.     print_shadow_line(Lpt,line_term,num_excluded);
  1151. #else
  1152.     print_shadow_line(pp,line_term,num_excluded);
  1153. #endif
  1154.     num_excluded = 0L;
  1155.    }
  1156. /*---------------------------------------------------------------------*/
  1157. /* If STAY is OFF, change the current and focus lines by the number    */
  1158. /* of lines calculated from the target.                                */
  1159. /*---------------------------------------------------------------------*/
  1160.  if (!CURRENT_VIEW->stay)                               /* stay is off */
  1161.    {
  1162.     CURRENT_VIEW->focus_line = min(CURRENT_VIEW->focus_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  1163.     CURRENT_VIEW->current_line = min(CURRENT_VIEW->current_line+num_lines-1L,CURRENT_FILE->number_lines+1L);
  1164.    }
  1165.  pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line);
  1166.  build_current_screen();
  1167.  display_current_screen();
  1168.  if (curses_started)
  1169.    {
  1170.     y = get_row_for_focus_line(CURRENT_VIEW->focus_line,
  1171.                                CURRENT_VIEW->current_row);
  1172.     if (CURRENT_VIEW->current_window == WINDOW_COMMAND)
  1173.        wmove(CURRENT_WINDOW_MAIN,y,x);
  1174.     else
  1175.        wmove(CURRENT_WINDOW,y,x);
  1176.    }
  1177. #ifdef TRACE
  1178.  trace_return();
  1179. #endif
  1180.  return;
  1181. }
  1182. #if defined(OS2)
  1183. /***********************************************************************/
  1184. #ifdef PROTO
  1185. void print_shadow_line(HFILE Lpt,CHARTYPE *line_term,LINETYPE num_excluded)
  1186. #else
  1187. void print_shadow_line(Lpt,line_term,num_excluded)
  1188. HFILE Lpt;
  1189. CHARTYPE *line_term;
  1190. LINETYPE num_excluded;
  1191. #endif
  1192. /***********************************************************************/
  1193. {
  1194. /*--------------------------- local data ------------------------------*/
  1195.  register short i=0;
  1196.  short num_dashes=0;
  1197.  CHARTYPE temp_buf[7]="";
  1198. #if defined(__32BIT__)
  1199.  ULONG NoWritten=0L;
  1200. #else
  1201.  USHORT NoWritten=0;
  1202. #endif
  1203. /*--------------------------- processing ------------------------------*/
  1204. #ifdef TRACE
  1205.  trace_function("commutil.c:print_shadow_line");
  1206. #endif
  1207.  if (CURRENT_VIEW->shadow)
  1208.    {
  1209.     num_dashes = (CURRENT_SCREEN.cols[WINDOW_MAIN] - 26) / 2;
  1210.     for (i=0;i<num_dashes;i++)
  1211.        DosWrite(Lpt,"-",1,&NoWritten);
  1212.     sprintf(temp_buf,"%6ld",num_excluded);
  1213.     DosWrite(Lpt,temp_buf,strlen(temp_buf),&NoWritten);
  1214.     DosWrite(Lpt," line(s) not displayed ",23,&NoWritten);
  1215.     for (i=0;i<num_dashes;i++)
  1216.        DosWrite(Lpt,"-",1,&NoWritten);
  1217.     DosWrite(Lpt,line_term,strlen(line_term),&NoWritten);
  1218.    }
  1219. #ifdef TRACE
  1220.  trace_return();
  1221. #endif
  1222.  return;
  1223. }
  1224. #else
  1225. /***********************************************************************/
  1226. #ifdef PROTO
  1227. void print_shadow_line(FILE *pp,CHARTYPE *line_term,LINETYPE num_excluded)
  1228. #else
  1229. void print_shadow_line(pp,line_term,num_excluded)
  1230. FILE *pp;
  1231. CHARTYPE *line_term;
  1232. LINETYPE num_excluded;
  1233. #endif
  1234. /***********************************************************************/
  1235. {
  1236. /*--------------------------- local data ------------------------------*/
  1237.  register short i=0;
  1238.  short num_dashes=0;
  1239. /*--------------------------- processing ------------------------------*/
  1240. #ifdef TRACE
  1241.  trace_function("commutil.c:print_shadow_line");
  1242. #endif
  1243.  if (CURRENT_VIEW->shadow)
  1244.    {
  1245.     num_dashes = (CURRENT_SCREEN.cols[WINDOW_MAIN] - 26) / 2;
  1246.     for (i=0;i<num_dashes;i++)
  1247.        fputc('-',pp);
  1248.     fprintf(pp,"%6ld line(s) not displayed ",num_excluded);
  1249.     for (i=0;i<num_dashes;i++)
  1250.        fputc('-',pp);
  1251.     fprintf(pp,"%s",line_term);
  1252.    }
  1253. #ifdef TRACE
  1254.  trace_return();
  1255. #endif
  1256.  return;
  1257. }
  1258. #endif
  1259. #endif
  1260. /***********************************************************************/
  1261. #ifdef PROTO
  1262. CHARTYPE next_char(LINE *curr,short *off,short end_col)
  1263. #else
  1264. CHARTYPE next_char(curr,off,end_col)
  1265. LINE *curr;
  1266. short *off;
  1267. short end_col;
  1268. #endif
  1269. /***********************************************************************/
  1270. {
  1271. /*--------------------------- local data ------------------------------*/
  1272. /*--------------------------- processing ------------------------------*/
  1273. #ifdef TRACE
  1274.  trace_function("commutil.c:next_char");
  1275. #endif
  1276.  if (*(off) < min(curr->length,end_col))
  1277.    {
  1278.     (*(off))++;
  1279. #ifdef TRACE
  1280.     trace_return();
  1281. #endif
  1282.     return(*(curr->line+((*(off))-1)));
  1283.    }
  1284.  *(off) = (-1);
  1285. #ifdef TRACE
  1286.  trace_return();
  1287. #endif
  1288.  return(0);
  1289. }
  1290. /***********************************************************************/
  1291. #ifdef PROTO
  1292. short add_define(int key_value,CHARTYPE *commands)
  1293. #else
  1294. short add_define(key_value,commands)
  1295. int key_value;
  1296. CHARTYPE *commands;
  1297. #endif
  1298. /***********************************************************************/
  1299. /* Parameters:                                                         */
  1300. /*  key_value: numeric representation of function key                  */
  1301. /*   commands: commands and parameters                                 */
  1302. /***********************************************************************/
  1303. {
  1304. /*-------------------------- external data ----------------------------*/
  1305. /*--------------------------- local data ------------------------------*/
  1306.  register short j=0;
  1307.  short cmd_nr=0;
  1308.  CHARTYPE *word[MAX_COMMANDS+1];
  1309.  unsigned short num_commands=0;
  1310.  CHARTYPE command_delim[2];
  1311.  short rc=RC_OK;
  1312.  CHARTYPE *command_entered=NULL,*cl_cmd=NULL,*cl_param=NULL;
  1313. /*--------------------------- processing ------------------------------*/
  1314. #ifdef TRACE
  1315.  trace_function("commutil.c:add_define");
  1316. #endif
  1317. /*---------------------------------------------------------------------*/
  1318. /* If the commands argument is empty, delet the definition of the key  */
  1319. /* definitions for the key, so just return.                            */
  1320. /*---------------------------------------------------------------------*/
  1321.  if (strcmp(commands,"") == 0)
  1322.    {
  1323.     remove_define(key_value);
  1324. #ifdef TRACE
  1325.     trace_return();
  1326. #endif
  1327.     return(RC_OK);
  1328.    }
  1329. /*---------------------------------------------------------------------*/
  1330. /* Copy the incoming commands, so we can play with it.                 */
  1331. /*---------------------------------------------------------------------*/
  1332.  if ((command_entered = (CHARTYPE *)my_strdup(commands)) == NULL)
  1333.    {
  1334.     display_error(30,(CHARTYPE *)"",FALSE);
  1335. #ifdef TRACE
  1336.     trace_return();
  1337. #endif
  1338.     return(RC_OUT_OF_MEMORY);
  1339.    }
  1340. /*---------------------------------------------------------------------*/
  1341. /* Allocate some space to cl_cmd and cl_param for the a command when   */
  1342. /* it is split into a command and its parameters.                      */
  1343. /*---------------------------------------------------------------------*/
  1344.  if ((cl_cmd = (CHARTYPE *)(*the_malloc)((strlen(commands)+1)*sizeof(CHARTYPE))) == NULL)
  1345.    {
  1346.     display_error(30,(CHARTYPE *)"",FALSE);
  1347. #ifdef TRACE
  1348.     trace_return();
  1349. #endif
  1350.     return(RC_OUT_OF_MEMORY);
  1351.    }
  1352.  if ((cl_param = (CHARTYPE *)(*the_malloc)((strlen(commands)+1)*sizeof(CHARTYPE))) == NULL)
  1353.    {
  1354.     display_error(30,(CHARTYPE *)"",FALSE);
  1355. #ifdef TRACE
  1356.     trace_return();
  1357. #endif
  1358.     return(RC_OUT_OF_MEMORY);
  1359.    }
  1360. /*---------------------------------------------------------------------*/
  1361. /* If [SET] LINENd is set to ON, split the args up into a number of    */
  1362. /* individual commands.                                                */
  1363. /*---------------------------------------------------------------------*/
  1364.  if (CURRENT_VIEW->linend_status)
  1365.    {
  1366.     command_delim[0] = CURRENT_VIEW->linend_value;
  1367.     command_delim[1] = '\0';
  1368.     num_commands = command_split(commands,word,MAX_COMMANDS,command_delim,command_entered);
  1369.    }
  1370.  else
  1371.    {
  1372.     word[0] = command_entered;
  1373.     num_commands = 1;
  1374.    }
  1375. /*---------------------------------------------------------------------*/
  1376. /* For each command entered, split it up into command and params, and  */
  1377. /* validate that each command is valid...                              */
  1378. /*---------------------------------------------------------------------*/
  1379.  for (j=0;j<num_commands;j++)
  1380.    {
  1381.     split_command(word[j],cl_cmd,cl_param);
  1382.     if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
  1383.       {
  1384.        display_error(21,cl_cmd,FALSE);
  1385.        rc = RC_INVALID_OPERAND;
  1386.        break;
  1387.       }
  1388.    }
  1389. /*---------------------------------------------------------------------*/
  1390. /* Now we know each command is valid, we can remove any prior          */
  1391. /* definition and assign the new one.                                  */
  1392. /*---------------------------------------------------------------------*/
  1393.  if (rc == RC_OK)
  1394.    {
  1395.     remove_define(key_value);
  1396.     for (j=0;j<num_commands;j++)
  1397.       {
  1398.        split_command(word[j],cl_cmd,cl_param);
  1399.        if ((cmd_nr = find_command(cl_cmd,FALSE)) == (-1))
  1400.          {
  1401.           display_error(21,cl_cmd,FALSE);      /* this should not be reached */
  1402.           rc = RC_INVALID_OPERAND;
  1403.           break;
  1404.          }
  1405.        rc = append_define(key_value,cmd_nr,cl_param);
  1406.        if (rc != RC_OK)
  1407.           break;
  1408.       }
  1409.    }
  1410.  (*the_free)(command_entered);
  1411.  (*the_free)(cl_cmd);
  1412.  (*the_free)(cl_param);
  1413. #ifdef TRACE
  1414.  trace_return();
  1415. #endif
  1416.  return(rc);
  1417. }
  1418. /***********************************************************************/
  1419. #ifdef PROTO
  1420. short remove_define(int key_value)
  1421. #else
  1422. short remove_define(key_value)
  1423. int key_value;
  1424. #endif
  1425. /***********************************************************************/
  1426. /* Parameters:                                                         */
  1427. /*  key_value: numeric representation of function key                  */
  1428. /***********************************************************************/
  1429. {
  1430. /*--------------------------- local data ------------------------------*/
  1431.  DEFINE *curr=NULL;
  1432. /*--------------------------- processing ------------------------------*/
  1433. #ifdef TRACE
  1434.  trace_function("commutil.c:remove_define");
  1435. #endif
  1436. /*---------------------------------------------------------------------*/
  1437. /* Find all items in the linked list for the key_value and remove them */
  1438. /* from the list.                                                      */
  1439. /*---------------------------------------------------------------------*/
  1440.  curr = first_define;
  1441.  while(curr != NULL)
  1442.    {
  1443.     if (curr->def_funkey == key_value)
  1444.       {
  1445.        if (curr->def_params != NULL)
  1446.           (*the_free)(curr->def_params);
  1447.        curr = dll_del(&first_define,&last_define,curr,DIRECTION_FORWARD);
  1448.       }
  1449.     else
  1450.        curr = curr->next;
  1451.    }
  1452. #ifdef TRACE
  1453.  trace_return();
  1454. #endif
  1455.  return(RC_OK);
  1456. }
  1457. /***********************************************************************/
  1458. #ifdef PROTO
  1459. short append_define(int key_value,short cmd,CHARTYPE *prm)
  1460. #else
  1461. short append_define(key_value,cmd,prm)
  1462. int key_value;
  1463. short cmd;
  1464. CHARTYPE *prm;
  1465. #endif
  1466. /***********************************************************************/
  1467. /* Parameters:                                                         */
  1468. /*  key_value: numeric representation of function key                  */
  1469. /***********************************************************************/
  1470. {
  1471. /*-------------------------- external data ----------------------------*/
  1472. /*--------------------------- local data ------------------------------*/
  1473.  DEFINE *curr=NULL;
  1474. /*--------------------------- processing ------------------------------*/
  1475. #ifdef TRACE
  1476.  trace_function("commutil.c:append_define");
  1477. #endif
  1478. /*---------------------------------------------------------------------*/
  1479. /* Find all items in the linked list for the key_value and remove them */
  1480. /* from the list.                                                      */
  1481. /*---------------------------------------------------------------------*/
  1482.  curr = dll_add(first_define,last_define,sizeof(DEFINE));
  1483.  if (curr == NULL)
  1484.    {
  1485.     display_error(30,(CHARTYPE *)"",FALSE);
  1486. #ifdef TRACE
  1487.     trace_return();
  1488. #endif
  1489.     return(RC_OUT_OF_MEMORY);
  1490.    }
  1491.  curr->def_params = (CHARTYPE *)(*the_malloc)((strlen(prm)+1)*sizeof(CHARTYPE));
  1492.  if (curr->def_params == NULL)
  1493.    {
  1494.     display_error(30,(CHARTYPE *)"",FALSE);
  1495. #ifdef TRACE
  1496.     trace_return();
  1497. #endif
  1498.     return(RC_OUT_OF_MEMORY);
  1499.    }
  1500.  strcpy(curr->def_params,prm);
  1501.  curr->def_funkey = key_value;
  1502.  curr->def_command = cmd;
  1503.  last_define = curr;
  1504.  if (first_define == NULL)
  1505.     first_define = last_define;
  1506. #ifdef TRACE
  1507.  trace_return();
  1508. #endif
  1509.  return(RC_OK);
  1510. }
  1511. /***********************************************************************/
  1512. #ifdef PROTO
  1513. int find_key_value(CHARTYPE *mnemonic)
  1514. #else
  1515. int find_key_value(mnemonic)
  1516. CHARTYPE *mnemonic;
  1517. #endif
  1518. /***********************************************************************/
  1519. /*   Function: find the matching key value for the supplied key name   */
  1520. /* Parameters:                                                         */
  1521. /*   mnemonic: the key name to be matched                              */
  1522. /***********************************************************************/
  1523. {
  1524. /*--------------------------- local data ------------------------------*/
  1525.  register short i=0;
  1526. /*--------------------------- processing ------------------------------*/
  1527. #ifdef TRACE
  1528.  trace_function("commutil.c:find_key_value");
  1529. #endif
  1530.  for (i=0;key_table[i].mnemonic!=NULL;i++)
  1531.     if (equal(key_table[i].mnemonic,mnemonic,strlen(key_table[i].mnemonic)))
  1532.       {
  1533. #ifdef TRACE
  1534.        trace_return();
  1535. #endif
  1536.        return(key_table[i].key_value);
  1537.       }
  1538. #ifdef TRACE
  1539.  trace_return();
  1540. #endif
  1541.  return(-1);
  1542. }
  1543. /***********************************************************************/
  1544. #ifdef PROTO
  1545. short find_command(CHARTYPE *cmd,bool search_for_target)
  1546. #else
  1547. short find_command(cmd,search_for_target)
  1548. CHARTYPE *cmd;
  1549. bool search_for_target;
  1550. #endif
  1551. /***********************************************************************/
  1552. /*   Function: determine if the string supplied is a valid abbrev for  */
  1553. /*             a command.                                              */
  1554. /* Parameters:                                                         */
  1555. /*        cmd:               the string to be checked                  */
  1556. /*        search_for_target: determine if command is a valid target    */
  1557. /***********************************************************************/
  1558. {
  1559. /*--------------------------- local data ------------------------------*/
  1560.  register short i=0;
  1561.  short rc=RC_OK;
  1562.  LINETYPE num_lines=0L;
  1563.  TARGET target;
  1564.  short target_type=TARGET_NORMAL|TARGET_BLOCK|TARGET_ALL;
  1565. /*--------------------------- processing ------------------------------*/
  1566. #ifdef TRACE
  1567.  trace_function("commutil.c:find_command");
  1568. #endif
  1569.  for (i=0;command[i].text != NULL;i++)
  1570.     if (equal(command[i].text,cmd,(command[i].min_len == 0) ? strlen(command[i].text) : command[i].min_len)
  1571.     &&  !command[i].sos_command)
  1572.       {
  1573. #ifdef TRACE
  1574.        trace_return();
  1575. #endif
  1576.        return(i);
  1577.       }
  1578. /*---------------------------------------------------------------------*/
  1579. /* To get here the command was not a 'command'. If we don't want to    */
  1580. /* search for targets, exit with (-1).                                 */
  1581. /*---------------------------------------------------------------------*/
  1582.  if (!search_for_target)
  1583.    {
  1584. #ifdef TRACE
  1585.     trace_return();
  1586. #endif
  1587.     return(-1);
  1588.    }
  1589. /*---------------------------------------------------------------------*/
  1590. /* Find if it is a valid target...                                     */
  1591. /*---------------------------------------------------------------------*/
  1592.  initialise_target(&target);
  1593.  rc = validate_target(cmd,&target,target_type,get_true_line(),TRUE,TRUE);
  1594.  if (rc != RC_OK
  1595.  &&  rc != RC_TARGET_NOT_FOUND)
  1596.    {
  1597.     free_target(&target);
  1598. #ifdef TRACE
  1599.     trace_return();
  1600. #endif
  1601.     return(-1);
  1602.    }
  1603.  free_target(&target);
  1604. /*---------------------------------------------------------------------*/
  1605. /* If a valid target, find 'LOCATE' command and return the index.      */
  1606. /*---------------------------------------------------------------------*/
  1607.  strcpy(temp_params,cmd);
  1608.  for (i=0;command[i].text != NULL;i++)
  1609.    {
  1610.     if (strcmp(command[i].text,"locate") == 0)
  1611.        break;
  1612.    }
  1613. #ifdef TRACE
  1614.  trace_return();
  1615. #endif
  1616.   return(i);
  1617. }
  1618. /***********************************************************************/
  1619. #ifdef PROTO
  1620. void init_command(void)
  1621. #else
  1622. void init_command()
  1623. #endif
  1624. /***********************************************************************/
  1625. {
  1626. /*--------------------------- local data ------------------------------*/
  1627.  register short i=0;
  1628. /*--------------------------- processing ------------------------------*/
  1629. #ifdef TRACE
  1630.  trace_function("commutil.c:init_command");
  1631. #endif
  1632.  for (i=0;i<MAX_SAVED_COMMANDS;i++)
  1633.      strcpy(cmd[i],"");
  1634. #ifdef TRACE
  1635.  trace_return();
  1636. #endif
  1637.  return;
  1638. }
  1639. /***********************************************************************/
  1640. #ifdef PROTO
  1641. void add_command(CHARTYPE *new_cmd)
  1642. #else
  1643. void add_command(new_cmd)
  1644. CHARTYPE *new_cmd;
  1645. #endif
  1646. /***********************************************************************/
  1647. {
  1648. /*--------------------------- local data ------------------------------*/
  1649. /*--------------------------- processing ------------------------------*/
  1650. #ifdef TRACE
  1651.  trace_function("commutil.c:add_command");
  1652. #endif
  1653.  offset_cmd = 0;
  1654. /*---------------------------------------------------------------------*/
  1655. /* If the command to be added is the same as the current command or if */
  1656. /* the command line is empty or if the command is "=" or "?", return   */
  1657. /* without adding command to array.                                    */
  1658. /*---------------------------------------------------------------------*/
  1659.  if (strcmp(new_cmd,cmd[current_cmd]) == 0
  1660.  || strcmp(new_cmd,"") == 0
  1661.  || strcmp(new_cmd,"=") == 0
  1662.  || new_cmd[0] == '?')
  1663.    {
  1664. #ifdef TRACE
  1665.     trace_return();
  1666. #endif
  1667.     return;
  1668.    }
  1669.  if (number_cmds == MAX_SAVED_COMMANDS)
  1670.     current_cmd = last_cmd = (last_cmd == MAX_SAVED_COMMANDS-1) ? 0 : ++last_cmd;
  1671.  else
  1672.     current_cmd = ++last_cmd;
  1673.  strcpy(cmd[current_cmd],new_cmd);
  1674.  number_cmds++;
  1675.  if (number_cmds > MAX_SAVED_COMMANDS)
  1676.     number_cmds = MAX_SAVED_COMMANDS;
  1677. #ifdef TRACE
  1678.  trace_return();
  1679. #endif
  1680.  return;
  1681. }
  1682. /***********************************************************************/
  1683. #ifdef PROTO
  1684. CHARTYPE *get_next_command( short direction)
  1685. #else
  1686. CHARTYPE *get_next_command(direction)
  1687. short direction;
  1688. #endif
  1689. /***********************************************************************/
  1690. {
  1691. /*--------------------------- local data ------------------------------*/
  1692.  CHARTYPE *cmd_to_return=NULL;
  1693. /*--------------------------- processing ------------------------------*/
  1694. #ifdef TRACE
  1695.  trace_function("commutil.c:get_next_command");
  1696. #endif
  1697.  if (number_cmds == 0)
  1698.    {
  1699. #ifdef TRACE
  1700.     trace_return();
  1701. #endif
  1702.     return((CHARTYPE *)NULL);
  1703.    }
  1704.  switch(direction)
  1705.    {
  1706.     case DIRECTION_BACKWARD:
  1707.          if (current_cmd+1 == number_cmds)
  1708.            {
  1709.             current_cmd = 0;
  1710.             cmd_to_return = cmd[current_cmd];
  1711.            }
  1712.          else
  1713.             cmd_to_return = cmd[++current_cmd];
  1714.          break;
  1715.     case DIRECTION_FORWARD:
  1716.          if (current_cmd+offset_cmd < 0)
  1717.            {
  1718.             current_cmd = number_cmds-1;
  1719.             cmd_to_return = cmd[current_cmd];
  1720.            }
  1721.          else
  1722.            {
  1723.             current_cmd = current_cmd+offset_cmd;
  1724.             cmd_to_return = cmd[current_cmd];
  1725.            }
  1726.          offset_cmd = (-1);
  1727.          break;
  1728.     case DIRECTION_NONE:
  1729.          cmd_to_return = cmd[current_cmd];
  1730.          break;
  1731.    }
  1732. #ifdef TRACE
  1733.  trace_return();
  1734. #endif
  1735.  return(cmd_to_return);
  1736. }
  1737. /***********************************************************************/
  1738. #ifdef PROTO
  1739. bool is_tab_col(LENGTHTYPE x)
  1740. #else
  1741. bool is_tab_col(x)
  1742. LENGTHTYPE x;
  1743. #endif
  1744. /***********************************************************************/
  1745. {
  1746. /*-------------------------- external data ----------------------------*/
  1747. /*--------------------------- local data ------------------------------*/
  1748.  register short i=0;
  1749.  bool rc=FALSE;
  1750. /*--------------------------- processing ------------------------------*/
  1751. #ifdef TRACE
  1752.  trace_function("commutil.c:is_tab_col");
  1753. #endif
  1754.  for (i=0;i<CURRENT_VIEW->numtabs;i++)
  1755.    {
  1756.     if (CURRENT_VIEW->tabs[i] == x)
  1757.       {
  1758.        rc = TRUE;
  1759.        break;
  1760.       }
  1761.    }
  1762. #ifdef TRACE
  1763.  trace_return();
  1764. #endif
  1765.  return(rc);
  1766. }
  1767. /***********************************************************************/
  1768. #ifdef PROTO
  1769. LENGTHTYPE find_next_tab_col(LENGTHTYPE x)
  1770. #else
  1771. LENGTHTYPE find_next_tab_col(x)
  1772. LENGTHTYPE x;
  1773. #endif
  1774. /***********************************************************************/
  1775. {
  1776. /*-------------------------- external data ----------------------------*/
  1777. /*--------------------------- local data ------------------------------*/
  1778.  register short i=0;
  1779.  LENGTHTYPE next_tab_col=0;
  1780. /*--------------------------- processing ------------------------------*/
  1781. #ifdef TRACE
  1782.  trace_function("commutil.c:find_next_tab_col");
  1783. #endif
  1784.  for (i=0;i<CURRENT_VIEW->numtabs;i++)
  1785.    {
  1786.     if (CURRENT_VIEW->tabs[i] > x)
  1787.       {
  1788.        next_tab_col = CURRENT_VIEW->tabs[i];
  1789.        break;
  1790.       }
  1791.    }
  1792. #ifdef TRACE
  1793.  trace_return();
  1794. #endif
  1795.  return(next_tab_col);
  1796. }
  1797. /***********************************************************************/
  1798. #ifdef PROTO
  1799. LENGTHTYPE find_prev_tab_col(LENGTHTYPE x)
  1800. #else
  1801. LENGTHTYPE find_prev_tab_col(x)
  1802. LENGTHTYPE x;
  1803. #endif
  1804. /***********************************************************************/
  1805. {
  1806. /*-------------------------- external data ----------------------------*/
  1807. /*--------------------------- local data ------------------------------*/
  1808.  register short i=0;
  1809.  LENGTHTYPE next_tab_col=0;
  1810. /*--------------------------- processing ------------------------------*/
  1811. #ifdef TRACE
  1812.  trace_function("commutil.c:find_prev_tab_col");
  1813. #endif
  1814.  for (i=CURRENT_VIEW->numtabs-1;i>-1;i--)
  1815.    {
  1816.     if (CURRENT_VIEW->tabs[i] < x)
  1817.       {
  1818.        next_tab_col = CURRENT_VIEW->tabs[i];
  1819.        break;
  1820.       }
  1821.    }
  1822. #ifdef TRACE
  1823.  trace_return();
  1824. #endif
  1825.  return(next_tab_col);
  1826. }
  1827. /***********************************************************************/
  1828. #ifdef PROTO
  1829. short tabs_convert(LINE *curr,bool expand_tabs,bool inc_alt,bool use_tabs,
  1830.                    bool add_to_recovery)
  1831. #else
  1832. short tabs_convert(curr,expand_tabs,inc_alt,use_tabs,add_to_recovery)
  1833. LINE *curr;
  1834. bool expand_tabs,inc_alt,use_tabs,add_to_recovery;
  1835. #endif
  1836. /***********************************************************************/
  1837. {
  1838. /*-------------------------- external data ----------------------------*/
  1839.  extern CHARTYPE *rec;
  1840.  extern CHARTYPE TABI_Nx;
  1841. /*--------------------------- local data ------------------------------*/
  1842.  register short i=0,j=0;
  1843.  bool expanded=FALSE;
  1844.  bool tabs_exhausted=FALSE;
  1845.  LENGTHTYPE tabcol=0;
  1846.  short rc=RC_OK;
  1847. /*--------------------------- processing ------------------------------*/
  1848. #ifdef TRACE
  1849.  trace_function("commutil.c:tabs_convert");
  1850. #endif
  1851. /*---------------------------------------------------------------------*/
  1852. /* If we are expanding tabs to spaces, do the following...             */
  1853. /*---------------------------------------------------------------------*/
  1854.  if (expand_tabs)
  1855.    {
  1856.     for (i=0,j=0;i<curr->length;i++)
  1857.      {
  1858.       if (curr->line[i] == '\t')
  1859.         {
  1860.          if (use_tabs)
  1861.            {
  1862.             if (tabs_exhausted)
  1863.               {
  1864.                rec[j++] = ' ';
  1865.                if (j >= max_line_length)
  1866.                   break;
  1867.               }
  1868.             else
  1869.               {
  1870.                tabcol = find_next_tab_col(j+1);
  1871.                if (tabcol == 0)
  1872.                   tabs_exhausted = TRUE;
  1873.                else
  1874.                  {
  1875.                   tabcol--;
  1876.                   do
  1877.                     {
  1878.                      rec[j++] = ' ';
  1879.                      if (j >= max_line_length)
  1880.                         break;
  1881.                     }
  1882.                   while (j<tabcol);
  1883.                  }
  1884.               }
  1885.            }
  1886.          else
  1887.            {
  1888.             do
  1889.               {
  1890.                rec[j++] = ' ';
  1891.                if (j >= max_line_length)
  1892.                   break;
  1893.               }
  1894.             while ((j % TABI_Nx) != 0);
  1895.            }
  1896.          expanded = TRUE;
  1897.         }
  1898.       else
  1899.         {
  1900.          rec[j++] = curr->line[i];
  1901.          if (j >= max_line_length)
  1902.            break;
  1903.         }
  1904.      }
  1905. /*---------------------------------------------------------------------*/
  1906. /* If we expanded tabs, we need to reallocate memory for the line.     */
  1907. /*---------------------------------------------------------------------*/
  1908.   if (expanded)
  1909.     {
  1910.      if (add_to_recovery)
  1911.         add_to_recovery_list(curr->line,curr->length);
  1912.      curr->line = (CHARTYPE *)(*the_realloc)((void *)curr->line,(j+1)*sizeof(CHARTYPE));
  1913.      if (curr->line == (CHARTYPE *)NULL)
  1914.        {
  1915.         display_error(30,"",FALSE);
  1916. #ifdef TRACE
  1917.         trace_return();
  1918. #endif
  1919.         return(RC_OUT_OF_MEMORY);
  1920.        }
  1921. /*---------------------------------------------------------------------*/
  1922. /* Copy the contents of rec into the line.                             */
  1923. /*---------------------------------------------------------------------*/
  1924.     memcpy(curr->line,rec,j);
  1925.     curr->length = j;
  1926.     *(curr->line+j) = '\0';
  1927. /*---------------------------------------------------------------------*/
  1928. /* Increment the number of alterations count.                          */
  1929. /*---------------------------------------------------------------------*/
  1930.     if (inc_alt)
  1931.       {
  1932.        if ((rc = increment_alt(CURRENT_FILE)) != RC_OK)
  1933.          {
  1934. #ifdef TRACE
  1935.          trace_return();
  1936. #endif
  1937.          return(rc);
  1938.         }
  1939.       }
  1940.     }
  1941.  }
  1942.  
  1943. #ifdef TRACE
  1944.  trace_return();
  1945. #endif
  1946.  return(RC_OK);
  1947. }
  1948. /***********************************************************************/
  1949. #ifdef PROTO
  1950. short convert_hex_strings(CHARTYPE *str)
  1951. #else
  1952. short convert_hex_strings(str)
  1953. CHARTYPE *str;
  1954. #endif
  1955. /***********************************************************************/
  1956. {
  1957. /*--------------------------- local data ------------------------------*/
  1958.  register short i=0;
  1959.  CHARTYPE *p=NULL;
  1960.  bool dec_char=FALSE;
  1961.  CHARTYPE temp_str[MAX_COMMAND_LENGTH];
  1962.  short num=0;
  1963.  CHARTYPE ch1=0,ch2=0;
  1964. /*--------------------------- processing ------------------------------*/
  1965. #ifdef TRACE
  1966.  trace_function("commutil.c:convert_hex_strings");
  1967. #endif
  1968. /*---------------------------------------------------------------------*/
  1969. /* Check if the string begins with d',D',x' or X'. If not return the   */
  1970. /* string unchanged.                                                   */
  1971. /*---------------------------------------------------------------------*/
  1972.  if ((*(str) == 'd'
  1973.  ||   *(str) == 'D'
  1974.  ||   *(str) == 'x'
  1975.  ||   *(str) == 'X')
  1976.  &&   *(str+1) == '\'')
  1977.     ;
  1978.  else
  1979.    {
  1980. #ifdef TRACE
  1981.     trace_return();
  1982. #endif
  1983.     return(strlen(str));
  1984.    }
  1985. /*---------------------------------------------------------------------*/
  1986. /* Check if the last character is a single quote. If not return (-1)   */
  1987. /* to indicate an error.                                               */
  1988. /*---------------------------------------------------------------------*/
  1989.  if (*(str+strlen(str)-1) != '\'')
  1990.    {
  1991. #ifdef TRACE
  1992.     trace_return();
  1993. #endif
  1994.     return((-1));
  1995.    }
  1996. /*---------------------------------------------------------------------*/
  1997. /* If we got here we can validate the contents of the string.          */
  1998. /*---------------------------------------------------------------------*/
  1999.  *(str+strlen(str)-1) = '\0';
  2000.  if (*(str) == 'd'
  2001.  ||  *(str) == 'D')
  2002.     dec_char = TRUE;
  2003.  else
  2004.     dec_char = FALSE;
  2005.  p = (CHARTYPE *)strtok(str+2," ");
  2006.  while(p != NULL)
  2007.    {
  2008.     switch(dec_char)
  2009.       {
  2010.        case TRUE: /* parse decimal number */
  2011.                   if (equal((CHARTYPE *)"000000",p,1))
  2012.                      temp_str[i++] = (CHARTYPE)0;
  2013.                   else
  2014.                     {
  2015.                      num = atoi(p);
  2016.                      if (num < 1 || num > 255)
  2017.                        {
  2018. #ifdef TRACE
  2019.                         trace_return();
  2020. #endif
  2021.                         return((-1));
  2022.                        }
  2023.                      temp_str[i++] = (CHARTYPE)num;
  2024.                     }
  2025.                   break;
  2026.        case FALSE: /* parse hexidecimal number */
  2027.                   ch1 = *(p);
  2028.                   ch2 = *(p+1);
  2029.                   if (strlen(p) != 2
  2030.                   || !isxdigit(ch1)
  2031.                   || !isxdigit(ch2))
  2032.                     {
  2033. #ifdef TRACE
  2034.                      trace_return();
  2035. #endif
  2036.                      return((-1));
  2037.                     }
  2038.                   if (isupper(ch1)!=0)
  2039.                      ch1 = tolower(ch1);
  2040.                   if (isupper(ch2)!=0)
  2041.                      ch2 = tolower(ch2);
  2042.                   num =  ((isdigit(ch1)!=0) ? ch1-48 : ch1-87) * 16;
  2043.                   num += ((isdigit(ch2)!=0) ? ch2-48 : ch2-87);
  2044.                   temp_str[i++] = (CHARTYPE)num;
  2045.                   break;
  2046.       }
  2047.     p = (CHARTYPE *)strtok(NULL," ");
  2048.    }
  2049. /*
  2050.  temp_str[i] = '\0';
  2051.  memcpy(str,temp_str,i+1);
  2052. */
  2053.  memcpy(str,temp_str,i);
  2054. #ifdef TRACE
  2055.  trace_return();
  2056. #endif
  2057.  return(i);
  2058. }
  2059. /***********************************************************************/
  2060. #ifdef PROTO
  2061. short marked_block(bool in_current_view)
  2062. #else
  2063. short marked_block(in_current_view)
  2064. bool in_current_view;
  2065. #endif
  2066. /***********************************************************************/
  2067. {
  2068. /*-------------------------- external data ----------------------------*/
  2069.  extern VIEW_DETAILS *vd_mark;
  2070.  extern bool in_profile;
  2071. /*--------------------------- local data ------------------------------*/
  2072. /*--------------------------- processing ------------------------------*/
  2073. #ifdef TRACE
  2074.  trace_function("commutil.c:marked_block");
  2075. #endif
  2076.  if (in_profile)                  /* block commands invalid in profile */
  2077.    {
  2078.     display_error(24,(CHARTYPE *)"",FALSE);
  2079. #ifdef TRACE
  2080.     trace_return();
  2081. #endif
  2082.     return(RC_INVALID_ENVIRON);
  2083.    }
  2084.  if (MARK_VIEW == (VIEW_DETAILS *)NULL)             /* no marked block */
  2085.    {
  2086.     display_error(44,(CHARTYPE *)"",FALSE);
  2087. #ifdef TRACE
  2088.     trace_return();
  2089. #endif
  2090.     return(RC_INVALID_ENVIRON);
  2091.    }
  2092.  if (MARK_VIEW != CURRENT_VIEW     /* marked block not in current view */
  2093.  && in_current_view)
  2094.    {
  2095.     display_error(45,(CHARTYPE *)"",FALSE);
  2096. #ifdef TRACE
  2097.     trace_return();
  2098. #endif
  2099.     return(RC_INVALID_ENVIRON);
  2100.    }
  2101. #ifdef TRACE
  2102.  trace_return();
  2103. #endif
  2104.  return(RC_OK);
  2105. }
  2106. /***********************************************************************/
  2107. #ifdef PROTO
  2108. short suspend_curses(void)
  2109. #else
  2110. short suspend_curses()
  2111. #endif
  2112. /***********************************************************************/
  2113. {
  2114. /*--------------------------- local data ------------------------------*/
  2115. /*--------------------------- processing ------------------------------*/
  2116. #ifdef TRACE
  2117.  trace_function("commutil.c:suspend_curses");
  2118. #endif
  2119. #ifdef UNIX
  2120. # if defined(USE_EXTCURSES)
  2121.  csavetty(FALSE);
  2122.  reset_shell_mode();
  2123. # else
  2124.  reset_shell_mode();
  2125. #  ifdef BSD
  2126.  noraw();
  2127.  nl();
  2128.  echo();
  2129.  nocbreak();
  2130. #  endif
  2131. # endif
  2132. #endif
  2133. #ifdef TRACE
  2134.  trace_return();
  2135. #endif
  2136.  return(RC_OK);
  2137. }
  2138. /***********************************************************************/
  2139. #ifdef PROTO
  2140. short resume_curses(void)
  2141. #else
  2142. short resume_curses()
  2143. #endif
  2144. /***********************************************************************/
  2145. {
  2146. /*--------------------------- local data ------------------------------*/
  2147. /*--------------------------- processing ------------------------------*/
  2148. #ifdef TRACE
  2149.  trace_function("commutil.c:resume_curses");
  2150. #endif
  2151. #ifdef UNIX
  2152. # if defined(USE_EXTCURSES)
  2153.  cresetty(FALSE);
  2154. # else
  2155.  reset_prog_mode();
  2156. #  ifdef BSD
  2157.  raw();
  2158.  nonl();
  2159.  noecho();
  2160.  cbreak();
  2161. #  endif
  2162. # endif
  2163. #endif
  2164. #ifdef TRACE
  2165.  trace_return();
  2166. #endif
  2167.  return(RC_OK);
  2168. }
  2169. /***********************************************************************/
  2170. #ifdef PROTO
  2171. short restore_THE(void)
  2172. #else
  2173. short restore_THE()
  2174. #endif
  2175. /***********************************************************************/
  2176. {
  2177. /*-------------------------- external data ----------------------------*/
  2178.  extern WINDOW *divider;
  2179.  extern WINDOW *foot;
  2180.  extern CHARTYPE display_screens;
  2181.  extern bool horizontal;
  2182.  extern bool curses_started;
  2183. /*--------------------------- local data ------------------------------*/
  2184.  unsigned short y=0,x=0;
  2185.  VIEW_DETAILS *save_current_view=NULL;
  2186.  CHARTYPE save_current_screen=0;
  2187. /*--------------------------- processing ------------------------------*/
  2188. #ifdef TRACE
  2189.  trace_function("commutil.c:restore_THE");
  2190. #endif
  2191. /*---------------------------------------------------------------------*/
  2192. /* If curses hasn't started, no point in doing anything...             */
  2193. /*---------------------------------------------------------------------*/
  2194.  if (!curses_started)
  2195.    {
  2196. #ifdef TRACE
  2197.     trace_return();
  2198. #endif
  2199.     return(RC_OK);
  2200.    }
  2201.  getyx(CURRENT_WINDOW,y,x);
  2202.  wclear(stdscr);
  2203.  refresh();
  2204.  if (display_screens > 1)
  2205.    {
  2206.     save_current_view = CURRENT_VIEW;
  2207.     save_current_screen = current_screen;
  2208.     CURRENT_VIEW = OTHER_SCREEN.screen_view; /* make other view current */
  2209.     current_screen = (current_screen==0)?1:0; /* make other screen current */
  2210.     touch_current_screen();
  2211.     refresh_current_screen();
  2212.     CURRENT_VIEW = save_current_view;
  2213.     current_screen = save_current_screen;
  2214.     if (!horizontal)
  2215.       {
  2216.        touchwin(divider);
  2217.        wnoutrefresh(divider);
  2218.       }
  2219.    }
  2220.  touch_current_screen();
  2221.  if (foot != (WINDOW *)NULL)
  2222.     touchwin(foot);
  2223.  wmove(CURRENT_WINDOW,y,x);
  2224. #ifdef TRACE
  2225.  trace_return();
  2226. #endif
  2227.  return(RC_OK);
  2228. }
  2229. /***********************************************************************/
  2230. #ifdef PROTO
  2231. short execute_set_sos_command(bool set_command,CHARTYPE *params)
  2232. #else
  2233. short execute_set_sos_command(set_command,params)
  2234. bool set_command;
  2235. CHARTYPE *params;
  2236. #endif
  2237. /***********************************************************************/
  2238. {
  2239. /*--------------------------- local data ------------------------------*/
  2240. #define SETSOS_PARAMS  2
  2241.  CHARTYPE *word[SETSOS_PARAMS+1];
  2242.  unsigned short num_params=0;
  2243.  short rc=RC_OK,command_index=0;
  2244. /*--------------------------- processing ------------------------------*/
  2245. #ifdef TRACE
  2246.  trace_function("commutil.c:execute_set_sos_command");
  2247. #endif
  2248.  num_params = param_split(params,word,SETSOS_PARAMS,WORD_DELIMS,TEMP_PARAM);
  2249.  if (num_params < 1)
  2250.    {
  2251.     display_error(1,(CHARTYPE *)"",FALSE);
  2252. #ifdef TRACE
  2253.     trace_return();
  2254. #endif
  2255.     return(RC_INVALID_OPERAND);
  2256.    }
  2257.  if ((command_index = valid_command_type(set_command,word[0])) == RC_NOT_COMMAND)
  2258.    {
  2259.     display_error(set_command ? 42 : 41,word[0],FALSE);
  2260. #ifdef TRACE
  2261.     trace_return();
  2262. #endif
  2263.     return(RC_INVALID_OPERAND);
  2264.    }
  2265.  rc = (*command[command_index].function)(word[1]);
  2266. #ifdef TRACE
  2267.  trace_return();
  2268. #endif
  2269.  return(rc);
  2270. }
  2271. /***********************************************************************/
  2272. #ifdef PROTO
  2273. short valid_command_type(bool set_command,CHARTYPE *cmd_line)
  2274. #else
  2275. short valid_command_type(set_command,cmd_line)
  2276. bool set_command;
  2277. CHARTYPE *cmd_line;
  2278. #endif
  2279. /***********************************************************************/
  2280. {
  2281. /*--------------------------- local data ------------------------------*/
  2282.  register short i=0;
  2283. /*--------------------------- processing ------------------------------*/
  2284. #ifdef TRACE
  2285.  trace_function("commutil.c:valid_command_type");
  2286. #endif
  2287.  for (i=0;command[i].text != NULL;i++)
  2288.     {
  2289. /*---------------------------------------------------------------------*/
  2290. /* If no command text, continue.                                       */
  2291. /*---------------------------------------------------------------------*/
  2292.      if (strcmp(command[i].text,"") == 0)
  2293.         continue;
  2294. /*---------------------------------------------------------------------*/
  2295. /* Check that the supplied command matches the command for the length  */
  2296. /* of the command and that the length is at least as long as the       */
  2297. /* necessary significance.                                             */
  2298. /*---------------------------------------------------------------------*/
  2299.      if (equal(command[i].text,cmd_line,command[i].min_len)
  2300.      && command[i].min_len != 0)
  2301.        {
  2302. #ifdef TRACE
  2303.         trace_return();
  2304. #endif
  2305.         if (set_command && command[i].set_command)
  2306.            return(i);
  2307.         if (!set_command && command[i].sos_command)
  2308.            return(i);
  2309.        }
  2310.     }
  2311. #ifdef TRACE
  2312.  trace_return();
  2313. #endif
  2314.  return(RC_NOT_COMMAND);
  2315. }
  2316. /***********************************************************************/
  2317. #ifdef PROTO
  2318. short allocate_temp_space(unsigned short length,CHARTYPE param_type)
  2319. #else
  2320. short allocate_temp_space(length,param_type)
  2321. unsigned short length;
  2322. CHARTYPE param_type;
  2323. #endif
  2324. /***********************************************************************/
  2325. {
  2326. /*--------------------------- local data ------------------------------*/
  2327.  CHARTYPE *temp_ptr=NULL;
  2328.  unsigned short *temp_length=NULL;
  2329. /*--------------------------- processing ------------------------------*/
  2330. #ifdef TRACE
  2331.  trace_function("commutil.c:allocate_temp_space");
  2332. #endif
  2333. /*---------------------------------------------------------------------*/
  2334. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2335. /*---------------------------------------------------------------------*/
  2336.  switch(param_type)
  2337.    {
  2338.     case TEMP_PARAM:
  2339.          temp_ptr = temp_params;
  2340.          temp_length = &length_temp_params;
  2341.          break;
  2342.     case TEMP_MACRO:
  2343.          temp_ptr = temp_macros;
  2344.          temp_length = &length_temp_macros;
  2345.          break;
  2346.     case TEMP_TMP_CMD:
  2347.          temp_ptr = tmp_cmd;
  2348.          temp_length = &length_tmp_cmd;
  2349.          break;
  2350.     case TEMP_TEMP_CMD:
  2351.          temp_ptr = temp_cmd;
  2352.          temp_length = &length_temp_cmd;
  2353.          break;
  2354.     default:
  2355.          return(-1);
  2356.          break;
  2357.    }
  2358.  if (*temp_length >= length)
  2359.    {
  2360. #ifdef TRACE
  2361.     trace_return();
  2362. #endif
  2363.     return(RC_OK);
  2364.    }
  2365.  if (temp_ptr == NULL)
  2366.     temp_ptr = (CHARTYPE *)(*the_malloc)(sizeof(CHARTYPE)*(length+1));
  2367.  else
  2368.     temp_ptr = (CHARTYPE *)(*the_realloc)(temp_ptr,sizeof(CHARTYPE)*(length+1));
  2369.  if (temp_ptr == NULL)
  2370.    {
  2371.     display_error(30,(CHARTYPE *)"",FALSE);
  2372. #ifdef TRACE
  2373.     trace_return();
  2374. #endif
  2375.     return(RC_OUT_OF_MEMORY);
  2376.    }
  2377. /*---------------------------------------------------------------------*/
  2378. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2379. /*---------------------------------------------------------------------*/
  2380.  switch(param_type)
  2381.    {
  2382.     case TEMP_PARAM:
  2383.          temp_params = temp_ptr;
  2384.          break;
  2385.     case TEMP_MACRO:
  2386.          temp_macros = temp_ptr;
  2387.          break;
  2388.     case TEMP_TMP_CMD:
  2389.          tmp_cmd = temp_ptr;
  2390.          break;
  2391.     case TEMP_TEMP_CMD:
  2392.          temp_cmd = temp_ptr;
  2393.          break;
  2394.     default:
  2395.          return(-1);
  2396.          break;
  2397.    }
  2398.  *temp_length = length;
  2399. #ifdef TRACE
  2400.  trace_return();
  2401. #endif
  2402.  return(RC_OK);
  2403. }
  2404. /***********************************************************************/
  2405. #ifdef PROTO
  2406. void free_temp_space(CHARTYPE param_type)
  2407. #else
  2408. void free_temp_space(param_type)
  2409. CHARTYPE param_type;
  2410. #endif
  2411. /***********************************************************************/
  2412. {
  2413. /*--------------------------- local data ------------------------------*/
  2414.  CHARTYPE *temp_ptr=NULL;
  2415.  unsigned short *temp_length=0;
  2416. /*--------------------------- processing ------------------------------*/
  2417. #ifdef TRACE
  2418.  trace_function("commutil.c:free_temp_space");
  2419. #endif
  2420. /*---------------------------------------------------------------------*/
  2421. /* Based on param_type, point param_ptr to appropriate buffer.         */
  2422. /*---------------------------------------------------------------------*/
  2423.  switch(param_type)
  2424.    {
  2425.     case TEMP_PARAM:
  2426.          temp_ptr    = temp_params;
  2427.          temp_params = NULL;
  2428.          temp_length = &length_temp_params;
  2429.          break;
  2430.     case TEMP_MACRO:
  2431.          temp_ptr    = temp_macros;
  2432.          temp_macros = NULL;
  2433.          temp_length = &length_temp_macros;
  2434.          break;
  2435.     case TEMP_TMP_CMD:
  2436.          temp_ptr = tmp_cmd;
  2437.          tmp_cmd  = NULL;
  2438.          temp_length = &length_tmp_cmd;
  2439.          break;
  2440.     case TEMP_TEMP_CMD:
  2441.          temp_ptr    = temp_cmd;
  2442.          temp_cmd    = NULL;
  2443.          temp_length = &length_temp_cmd;
  2444.          break;
  2445.     default:
  2446.          return;
  2447.          break;
  2448.    }
  2449.  (*the_free)(temp_ptr);
  2450.  *temp_length = 0;
  2451. #ifdef TRACE
  2452.  trace_return();
  2453. #endif
  2454.  return;
  2455. }
  2456. /***********************************************************************/
  2457. #ifdef PROTO
  2458. CHARTYPE calculate_actual_row(CHARTYPE base,short off,CHARTYPE rows)
  2459. #else
  2460. CHARTYPE calculate_actual_row(base,off,rows)
  2461. CHARTYPE base,rows;
  2462. short off;
  2463. #endif
  2464. /***********************************************************************/
  2465. {
  2466. /*--------------------------- local data ------------------------------*/
  2467.  short row=0;
  2468. /*--------------------------- processing ------------------------------*/
  2469. #ifdef TRACE
  2470.  trace_function("commutil.c:calculate_actual_row");
  2471. #endif
  2472.  switch(base)
  2473.    {
  2474.     case POSITION_TOP:
  2475.                      row = off;
  2476.                      break;
  2477.     case POSITION_MIDDLE:
  2478.                      row = (rows /2 ) + off;
  2479.                      break;
  2480.     case POSITION_BOTTOM:
  2481.                      row = rows+off+1;
  2482.                      break;
  2483.    }
  2484. /*---------------------------------------------------------------------*/
  2485. /* If the calculated row is outside the screen size, default to middle.*/
  2486. /*---------------------------------------------------------------------*/
  2487.  if (row < 0 || row > rows)
  2488.     row = rows / 2;
  2489. #ifdef TRACE
  2490.  trace_return();
  2491. #endif
  2492.  return((CHARTYPE)row-1);
  2493. }
  2494. /*man***************************************************************************
  2495. NAME
  2496.      get_valid_macro_file_name
  2497.  
  2498. SYNOPSIS
  2499.      short get_valid_macro_file_name(macroname,filename,errnum)
  2500.      CHARTYPE *macroname;
  2501.      CHARTYPE *filename;
  2502.      short *errnum;
  2503.  
  2504. DESCRIPTION
  2505.      The get_valid_macro_file_name function determines the fully qualified
  2506.      file name for the supplied macroname.
  2507.  
  2508.      If the macroname contains any path specifiers, then the macro name
  2509.      is used as the filename and a check is made to ensure that the file
  2510.      exists and is readable.
  2511.  
  2512.      If the macroname does not contain any path specifiers, each
  2513.      directory in the MACROPATH variable is searched for a file that
  2514.      consists of the macroname appended with the current value for
  2515.      MACROEXT. If a file is found, it is checked to ensure it is
  2516.      readable.
  2517.  
  2518. RETURN VALUE
  2519.      If a file is found based on the above matching process, the fully
  2520.      qualified file name is copied into filename, errnum is set to 0
  2521.      and the function returns with RC_OK.
  2522.  
  2523.      If a file is not found, the macroname is copied into filename, the
  2524.      error number of the error message is copied into errnum and the
  2525.      function returns with RC_FILE_NOT_FOUND.
  2526.  
  2527.      If a file is found but the file is not readable, the macroname is
  2528.      copied into filename, the error number of the error message is
  2529.      copied into errnum and the function returns with RC_ACCESS_DENIED.
  2530. *******************************************************************************/
  2531. #ifdef PROTO
  2532. short get_valid_macro_file_name(CHARTYPE *macroname,CHARTYPE *filename,short *errnum)
  2533. #else
  2534. short get_valid_macro_file_name(macroname,filename,errnum)
  2535. CHARTYPE *macroname,*filename;
  2536. short *errnum;
  2537. #endif
  2538. /***********************************************************************/
  2539. {
  2540. #if defined(UNIX)
  2541. #   define PATH_DELIM ":"
  2542. #else
  2543. #   define PATH_DELIM ";"
  2544. #endif
  2545. /*-------------------------- external data ----------------------------*/
  2546.  extern CHARTYPE the_macro_path[MAX_FILE_NAME+1] ;
  2547.  extern CHARTYPE sp_path[MAX_FILE_NAME+1] ;
  2548.  extern CHARTYPE sp_fname[MAX_FILE_NAME+1] ;
  2549.  extern CHARTYPE macro_suffix[12];
  2550. /*--------------------------- local data ------------------------------*/
  2551.  register short i=0;
  2552.  CHARTYPE delims[3];
  2553.  bool file_found=FALSE;
  2554.  CHARTYPE *path[MAX_MACRO_DIRS+1];    /* max number of macro dirs */
  2555.  unsigned short num_params=0;
  2556. /*--------------------------- processing ------------------------------*/
  2557. #ifdef TRACE
  2558.  trace_function("commutil.c:get_valid_macro_file_name");
  2559. #endif
  2560. /*---------------------------------------------------------------------*/
  2561. /* Create the full name of the macro file by prepending the default    */
  2562. /* macropath provided the filename does not already contain a path.    */
  2563. /*---------------------------------------------------------------------*/
  2564.  (void *)strtrans(macroname,OSLASH,ISLASH);
  2565. #ifdef UNIX
  2566.  strcpy(delims,ISTR_SLASH);
  2567.  if (strpbrk(macroname,delims) == NULL
  2568.  && *(macroname) != '~')
  2569. #endif
  2570. #if defined(DOS) || defined(OS2)
  2571.  strcpy(delims,ISTR_SLASH);
  2572.  strcat(delims,":");
  2573.  if (strpbrk(macroname,delims) == NULL)
  2574. #endif
  2575. /*---------------------------------------------------------------------*/
  2576. /* The supplied macro file name does not contain a path...so for each  */
  2577. /* directory in the_macro_path, try to find the supplied file in that  */
  2578. /* directory.                                                          */
  2579. /*---------------------------------------------------------------------*/
  2580.    {
  2581.     strcpy(filename,the_macro_path);
  2582.     num_params = param_split(filename,path,MAX_MACRO_DIRS,PATH_DELIM,TEMP_MACRO);
  2583.     file_found = FALSE;
  2584.     for (i=0;i<num_params;i++)
  2585.       {
  2586.        strcpy(filename,path[i]);
  2587.        if (strlen(filename) == 0)
  2588.           continue;
  2589.        if (*(filename+strlen(filename)-1) != ISLASH)
  2590.           strcat(filename,ISTR_SLASH);
  2591.        strcat(filename,macroname);               /* append the file name */
  2592.        strcat(filename,macro_suffix);         /* append default suffix */
  2593.        if (file_exists(filename))           /* check if file exists... */
  2594.          {
  2595.           file_found = TRUE;
  2596.           break;
  2597.          }
  2598.       }
  2599.     if (!file_found)
  2600.       {
  2601.        strcpy(filename,macroname);
  2602.        strcat(filename,macro_suffix);
  2603.        *errnum = 11;
  2604. #ifdef TRACE
  2605.        trace_return();
  2606. #endif
  2607.        return(RC_FILE_NOT_FOUND);
  2608.       }
  2609.    }
  2610.  else                                /* file contains a path specifier */
  2611. /*---------------------------------------------------------------------*/
  2612. /* The supplied macro file name does contain a path...so just check to */
  2613. /* ensure that the file exists.                                        */
  2614. /*---------------------------------------------------------------------*/
  2615.    {
  2616.     if (splitpath(macroname) != RC_OK)
  2617.       {
  2618.        *errnum = 9;
  2619. #ifdef TRACE
  2620.        trace_return();
  2621. #endif
  2622.        return(RC_FILE_NOT_FOUND);
  2623.       }
  2624.     strcpy(filename,sp_path);
  2625.     strcat(filename,sp_fname);
  2626.     if (!file_exists(filename)
  2627.     ||  strcmp(sp_fname,"") == 0)
  2628.       {
  2629.        *errnum = 9;
  2630. #ifdef TRACE
  2631.        trace_return();
  2632. #endif
  2633.        return(RC_FILE_NOT_FOUND);
  2634.       }
  2635.    }
  2636. /*---------------------------------------------------------------------*/
  2637. /* If the file is not readable, error.                                 */
  2638. /*---------------------------------------------------------------------*/
  2639.  if (!file_readable(filename))
  2640.    {
  2641.     *errnum = 8;
  2642. #ifdef TRACE
  2643.     trace_return();
  2644. #endif
  2645.     return(RC_ACCESS_DENIED);
  2646.    }
  2647. #ifdef TRACE
  2648.  trace_return();
  2649. #endif
  2650.  *errnum = 0;
  2651.  return(RC_OK);
  2652. }
  2653. /***********************************************************************/
  2654. #ifdef PROTO
  2655. bool define_command(CHARTYPE *cmd_line)
  2656. #else
  2657. bool define_command(cmd_line)
  2658. CHARTYPE *cmd_line;
  2659. #endif
  2660. /***********************************************************************/
  2661. {
  2662. /*-------------------------- external data ----------------------------*/
  2663. /*--------------------------- local data ------------------------------*/
  2664.  register short i=0;
  2665.  CHARTYPE buf[7];
  2666. /*--------------------------- processing ------------------------------*/
  2667. #ifdef TRACE
  2668.  trace_function("commutil.c:define_command");
  2669. #endif
  2670. /*---------------------------------------------------------------------*/
  2671. /* First check if the command is a synonym, and use the real name to   */
  2672. /* search the command array.                                           */
  2673. /*---------------------------------------------------------------------*/
  2674.  
  2675.  memset(buf,'\0',7);
  2676.  memcpy(buf,cmd_line,min(6,strlen(cmd_line)));
  2677.  for (i=0;i<7;i++)
  2678.    {
  2679.     if (buf[i] == ' ')
  2680.        buf[i] = '\0';
  2681.    }
  2682.  if ((i = find_command(buf,FALSE)) == (-1))
  2683.    {
  2684. #ifdef TRACE
  2685.     trace_return();
  2686. #endif
  2687.     return(FALSE);
  2688.    }
  2689.  if (strcmp("define",command[i].text) == 0)
  2690.    {
  2691. #ifdef TRACE
  2692.     trace_return();
  2693. #endif
  2694.     return(TRUE);
  2695.    }
  2696. #ifdef TRACE
  2697.  trace_return();
  2698. #endif
  2699.  return(FALSE);
  2700. }
  2701. /***********************************************************************/
  2702. #ifdef PROTO
  2703. void touch_current_screen(void)
  2704. #else
  2705. void touch_current_screen()
  2706. #endif
  2707. /***********************************************************************/
  2708. {
  2709. /*-------------------------- external data ----------------------------*/
  2710. /*--------------------------- local data ------------------------------*/
  2711. /*--------------------------- processing ------------------------------*/
  2712. #ifdef TRACE
  2713.  trace_function("commutil.c:touch_current_screen");
  2714. #endif
  2715.  if (CURRENT_WINDOW_PREFIX != (WINDOW *)NULL)
  2716.     touchwin(CURRENT_WINDOW_PREFIX);
  2717.  if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  2718.     touchwin(CURRENT_WINDOW_COMMAND);
  2719.  touchwin(CURRENT_WINDOW_MAIN);
  2720.  touchwin(CURRENT_WINDOW_IDLINE);
  2721.  if (CURRENT_WINDOW_ARROW != (WINDOW *)NULL)
  2722.     touchwin(CURRENT_WINDOW_ARROW);
  2723. #ifdef TRACE
  2724.  trace_return();
  2725. #endif
  2726.  return;
  2727. }
  2728. /***********************************************************************/
  2729. #ifdef PROTO
  2730. void refresh_current_screen(void)
  2731. #else
  2732. void refresh_current_screen()
  2733. #endif
  2734. /***********************************************************************/
  2735. {
  2736. /*-------------------------- external data ----------------------------*/
  2737. /*--------------------------- local data ------------------------------*/
  2738. /*--------------------------- processing ------------------------------*/
  2739. #ifdef TRACE
  2740.  trace_function("commutil.c:refresh_current_screen");
  2741. #endif
  2742.  show_heading();
  2743.  wnoutrefresh(CURRENT_WINDOW_MAIN);
  2744.  if (CURRENT_WINDOW_PREFIX != (WINDOW *)NULL)
  2745.     wnoutrefresh(CURRENT_WINDOW_PREFIX);
  2746.  if (CURRENT_WINDOW_COMMAND != (WINDOW *)NULL)
  2747.     wnoutrefresh(CURRENT_WINDOW_COMMAND);
  2748.  if (CURRENT_WINDOW_ARROW != (WINDOW *)NULL)
  2749.    {
  2750.     touchwin(CURRENT_WINDOW_ARROW);
  2751.     wnoutrefresh(CURRENT_WINDOW_ARROW);
  2752.    }
  2753.  wnoutrefresh(CURRENT_WINDOW);
  2754. #ifdef TRACE
  2755.  trace_return();
  2756. #endif
  2757.  return;
  2758. }
  2759. /***********************************************************************/
  2760. #ifdef PROTO
  2761. void redraw_screen(CHARTYPE scrn)
  2762. #else
  2763. void redraw_screen(scrn)
  2764. CHARTYPE scrn;
  2765. #endif
  2766. /***********************************************************************/
  2767. {
  2768. /*-------------------------- external data ----------------------------*/
  2769.  extern bool curses_started;
  2770. /*--------------------------- local data ------------------------------*/
  2771. /*--------------------------- processing ------------------------------*/
  2772. #ifdef TRACE
  2773.  trace_function("commutil.c:redraw_screen");
  2774. #endif
  2775.  if (curses_started)
  2776.    {
  2777.     if (screen[scrn].win[WINDOW_COMMAND] != NULL)
  2778.       {
  2779.        wattrset(screen[scrn].win[WINDOW_COMMAND],set_colour(screen[scrn].screen_view->file_for_view->attr+ATTR_CMDLINE));
  2780.        touchwin(screen[scrn].win[WINDOW_COMMAND]);
  2781.        wnoutrefresh(screen[scrn].win[WINDOW_COMMAND]);
  2782.       }
  2783.     if (screen[scrn].win[WINDOW_ARROW] != NULL)
  2784.       {
  2785.        wattrset(screen[scrn].win[WINDOW_ARROW],set_colour(screen[scrn].screen_view->file_for_view->attr+ATTR_ARROW));
  2786.        redraw_window(screen[scrn].win[WINDOW_ARROW]);
  2787.        wnoutrefresh(screen[scrn].win[WINDOW_ARROW]);
  2788.       }
  2789.     if (screen[scrn].win[WINDOW_IDLINE] != NULL)
  2790.       {
  2791.        wattrset(screen[scrn].win[WINDOW_IDLINE],set_colour(screen[scrn].screen_view->file_for_view->attr+ATTR_IDLINE));
  2792.        redraw_window(screen[scrn].win[WINDOW_IDLINE]);
  2793.       }
  2794.     if (screen[scrn].win[WINDOW_PREFIX] != NULL)
  2795.        touchwin(screen[scrn].win[WINDOW_PREFIX]);
  2796.     touchwin(screen[scrn].win[WINDOW_MAIN]);
  2797.    }
  2798. #ifdef TRACE
  2799.  trace_return();
  2800. #endif
  2801.  return;
  2802. }
  2803.